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:
thing
is nil. This might happen in the case of things likecreate
permission, which doesn't take a specific object (it takes the class instead).permission.thing_id
is nil. This is dealing with the case where thePermission
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- 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
Why Is the Splat Used Inside an Array Definition Here
Search for "Enabled" Users in Net-Ldap for Ruby
Can't Install Ruby via Rvm, Error Running '_Rvm_Make -J4' on Ubuntu 22.04
Ruby Is Already Using the Class Name of My Model
Unexpected Value of _Callee_ When Including a Module - Is This a Ruby Bug
Web Page Scraping Gems/Tools Available in Ruby
How to Make a Ruby Enumerator That Does Lazy Iteration Through Two Other Enumerators
Remove a Tag But Keep the Text
Fast-Stemmer Installation Problems
Ruby: Cannot Install Watir Gem on Windows
Rails 7 Signup Form Doesn't Show Error Messages
Ruby on Rails: Params Is Nil. Undefined Method '[]' for Nil:Nilclass
Ruby Class Object Garbage Collection
How to Define a Method in Ruby Using Splat and an Optional Hash at the Same Time
Ruby on Rails. Bundler. Cucumber. Rake Aborted! Command Failed with Status (1)