Cancan Abilities in Separate File

Is it possible to use cancan with two ability class

...that said, you can use multiple ability models directly if you prefer:

class UserAbility
include CanCan::Ability

def initialize(user)
can :read, :all
end
end

class AdminAbility
include CanCan::Ability

def initialize(admin)
can :manage, :all
end
end

class ApplicationController < ActionController::Base
# overriding CanCan::ControllerAdditions
def current_ability
if current_account.kind_of?(AdminUser)
@current_ability ||= AdminAbility.new(current_account)
else
@current_ability ||= UserAbility.new(current_account)
end
end
end

How can Cancan ability handle two user models

You need to specify what models certain users can manipulate and perform actions on in your ability.rb file.

class Ability
include CanCan::Ability

# usual setup
def initialize(user)
user ||= User.new

if user.has_role? :admin
can :manage, :all
end

if user.has_role? :less_important_role
can [:read, :update], Model1
can :manage, Model2
end
end
end

Checkout the docs to read more about defining abilities.

Is it possible to condition CanCan abilities on a date attribute range?

You can define a block for conditions

can :some_action, Widget do |widget|
widget.date.to_time > Time.now
end

If the block returns true then the user has that ability, otherwise he will be denied access.

Refer this for more info

Rails CanCan gem refactoring Ability class

Simple escenario: If you can split the permissions in several mutually exclusive sets, then you should check this proposal from @ryanb, CanCan creator, in which he splits the abilities into several different classes and then overwrites the current_ability method in the ApplicationController

How you can break up large Ability class in CanCan - Gists

More complex scenario: if you have several different overlapping permissions sets, you can try this approach:

# app/models/ability.rb

class Ability
include CanCan::Ability

def initialize(user)
self.merge Abilities::Everyone.new(user)

if user
self.merge Abilities::Admin.new(user) if user.admin?
self.merge Abilities::Authenticated.new(user)
else
self.merge Abilities::Guest.new(user)
end
end
end

# app/models/abilities/admin.rb
module Abilities
class Admin
include CanCan::Ability

def initialize(user)
# define abilities here ...
end
end
end

# app/models/abilities/everyone.rb
...

And so on for the rest of the files.

CanCan and ability block

So, according to the CanCan docs, when you pass a block to can (which is what's going on here), the permission is given only if the block returns true. The object passed in to the block is the object that the user might have permission to do something to.

What this does, then, is give the user permission to perform permission.action on the class permission.thing_type if:

  1. thing is nil. This might happen in the case of things like create permission, which doesn't take a specific object (it takes the class instead).
  2. permission.thing_id is nil. This is dealing with the case where the Permission object doesn't point at a specific thing. This feels like the opposite side of item 1. It might apply in the case of 'blanket' permissions - a permission that says a particular user can perform this action on any object of this class. OR
  3. The thing has the id specified in the permission object.

Moral: Comment your code. Even if it's obvious to you right now what something does, it might not be to the next person. Who might also be you, in a few months.

How to do authorization with CanCan when I have a User and a separate Admin

You're going to need to test what type of object is being used for authorization in your cancan abilities file.

Something like the following:

class Ability
include CanCan::Ability

def initialize(user_or_admin)

case user_or_admin.class.name
when 'User'
can :read, :post
when 'Admin'
can :manage, :all
else
user = User.new # guest user
# ... other permissions for guests
end

end
end

CanCan abilities via Database and load_resource

As stated in docs you should use helper method:

  skip_authorize_resource :only => :index


Related Topics



Leave a reply



Submit