Reputation: 33785
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
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
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
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
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