marcamillion
marcamillion

Reputation: 33785

How do I get my ability.rb to work properly for my index action?

This is what my ability.rb looks like:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.has_role? :admin
      can :manage, :all
    end

    can :manage, Connection, inviter_user_id: user.id

  end
end

In my controller I have this:

class ConnectionsController < ApplicationController
  load_and_authorize_resource
  skip_authorize_resource only: :index

  layout 'connections'

  def index
     @family_tree = current_user.family_tree
     @inviter_connections = current_user.inviter_connections.order("updated_at desc")
     @invited_connections = current_user.invited_connections.order("updated_at desc")
  end
end

In my application_controller.rb, I have this:

  rescue_from CanCan::AccessDenied do |exception|
    redirect_to authenticated_root_url, :alert => exception.message
  end

Yet, when I try to visit /connections when I am not logged in, I get this error:

NoMethodError at /connections
undefined method `family_tree' for nil:NilClass

Also, when I remove the can :manage, Connection from my ability.rb it actually sends me to my login page like I expect.

How do I get both to work?

Upvotes: 1

Views: 347

Answers (4)

stevec
stevec

Reputation: 52768

It could also happen if you forgot to put this at the top of the controller:

load_and_authorize_resource

See docs for more.

Upvotes: 0

Lucas Moulin
Lucas Moulin

Reputation: 2550

It looks like you are using Devise for authentication. For this kind of validation when using devise you should add this to your controller:

before_action :authenticate_user!

Upvotes: 2

Woahdae
Woahdae

Reputation: 5051

On line 8 of your controller, current_user is nil when you're not logged in, and it's calling family_tree on it.

You need something like (just as an example, it depends on your needs):

 @family_tree = current_user.try(:family_tree) || FamilyTree.new

The reason it "works" when you remove the line in Ability is because that removes the ability to see the connection, so the before_filter redirects before you ever get inside index. What's probably tripping you up is the Connection record has a inviter_user_id of nil, and User#id is nil, so it's giving you permission to get into index.

Upvotes: 0

Dharam Gollapudi
Dharam Gollapudi

Reputation: 6438

Try the following:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)

    if user.has_role? :admin
      can :manage, :all
    else
      can :manage, Connection, inviter_user_id: user.id
    end

  end
end

Also, noticed that you are skip_authorize_resource only: :index, try commenting out that and see if it works.

Upvotes: 0

Related Questions