Module: CanCan::Ability
- Defined in:
- lib/cancan/ability.rb
Overview
This module is designed to be included into an Ability class. This will provide the “can” methods for defining and checking abilities.
class Ability
include CanCan::Ability
def initialize(user)
if user.admin?
can :manage, :all
else
can :read, :all
end
end
end
Instance Attribute Summary collapse
-
#user ⇒ Object
Returns the value of attribute user.
Instance Method Summary collapse
-
#alias_action(*args) ⇒ Object
Alias one or more actions into another one.
-
#aliased_actions ⇒ Object
Returns a hash of aliased actions.
-
#can(action, noun, &block) ⇒ Object
Defines which abilities are allowed using two arguments.
-
#can?(action, noun) ⇒ Boolean
Use to check the user’s permission for a given action and object.
-
#cannot(action, noun, &block) ⇒ Object
Define an ability which cannot be done.
-
#cannot?(*args) ⇒ Boolean
Convenience method which works the same as “can?” but returns the opposite value.
-
#clear_aliased_actions ⇒ Object
Removes previously aliased actions including the defaults.
Instance Attribute Details
#user ⇒ Object
Returns the value of attribute user.
19 20 21 |
# File 'lib/cancan/ability.rb', line 19 def user @user end |
Instance Method Details
#alias_action(*args) ⇒ Object
Alias one or more actions into another one.
alias_action :update, :destroy, :to => :modify
can :modify, Comment
Then :modify permission will apply to both :update and :destroy requests.
can? :update, Comment # => true
can? :destroy, Comment # => true
This only works in one direction. Passing the aliased action into the “can?” call will not work because aliases are meant to generate more generic actions.
alias_action :update, :destroy, :to => :modify
can :update, Comment
can? :modify, Comment # => false
Unless that exact alias is used.
can :modify, Comment
can? :modify, Comment # => true
The following aliases are added by default for conveniently mapping common controller actions.
alias_action :index, :show, :to => :read
alias_action :new, :to => :create
alias_action :edit, :to => :update
This way one can use params in the controller to determine the permission.
157 158 159 160 161 |
# File 'lib/cancan/ability.rb', line 157 def alias_action(*args) target = args.pop[:to] aliased_actions[target] ||= [] aliased_actions[target] += args end |
#aliased_actions ⇒ Object
Returns a hash of aliased actions. The key is the target and the value is an array of actions aliasing the key.
164 165 166 |
# File 'lib/cancan/ability.rb', line 164 def aliased_actions @aliased_actions ||= default_alias_actions end |
#can(action, noun, &block) ⇒ Object
Defines which abilities are allowed using two arguments. The first one is the action you’re setting the permission for, the second one is the class of object you’re setting it on.
can :update, Article
You can pass an array for either of these parameters to match any one.
can [:update, :destroy], [Article, Comment]
In this case the user has the ability to update or destroy both articles and comments.
You can pass a block to provide logic based on the article’s attributes.
can :update, Article do |article|
article && article.user == user
end
If the block returns true then the user has that :update ability for that article, otherwise he will be denied access. It’s possible for the passed in model to be nil if one isn’t specified, so be sure to take that into consideration.
You can pass :all to reference every type of object. In this case the object type will be passed into the block as well (just in case object is nil).
can :read, :all do |object_class, object|
object_class != Order
end
Here the user has permission to read all objects except orders.
You can also pass :manage as the action which will match any action. In this case the action is passed to the block.
can :manage, Comment do |action, comment|
action != :destroy
end
You can pass custom objects into this “can” method, this is usually done through a symbol and is useful if a class isn’t available to define permissions on.
can :read, :stats
can? :read, :stats # => true
106 107 108 109 |
# File 'lib/cancan/ability.rb', line 106 def can(action, noun, &block) @can_definitions ||= [] @can_definitions << [true, action, noun, block] end |
#can?(action, noun) ⇒ Boolean
Use to check the user’s permission for a given action and object.
can? :destroy, @project
You can also pass the class instead of an instance (if you don’t have one handy).
can? :create, Project
Not only can you use the can? method in the controller and view (see ControllerAdditions), but you can also call it directly on an ability instance.
ability.can? :destroy, @project
This makes testing a user’s abilities very easy.
def test "user can only destroy projects which he owns"
user = User.new
ability = Ability.new(user)
assert ability.can?(:destroy, Project.new(:user => user))
assert ability.cannot?(:destroy, Project.new)
end
43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/cancan/ability.rb', line 43 def can?(action, noun) (@can_definitions || []).reverse.each do |base_behavior, defined_action, defined_noun, defined_block| defined_actions = (defined_action) defined_nouns = [defined_noun].flatten if includes_action?(defined_actions, action) && includes_noun?(defined_nouns, noun) result = can_perform_action?(action, noun, defined_actions, defined_nouns, defined_block) return base_behavior ? result : !result end end false end |
#cannot(action, noun, &block) ⇒ Object
Define an ability which cannot be done. Accepts the same arguments as “can”.
can :read, :all
cannot :read, Comment
A block can be passed just like “can”, however if the logic is complex it is recommended to use the “can” method.
cannot :read, Product do |product|
product.invisible?
end
123 124 125 126 |
# File 'lib/cancan/ability.rb', line 123 def cannot(action, noun, &block) @can_definitions ||= [] @can_definitions << [false, action, noun, block] end |
#cannot?(*args) ⇒ Boolean
Convenience method which works the same as “can?” but returns the opposite value.
cannot? :destroy, @project
59 60 61 |
# File 'lib/cancan/ability.rb', line 59 def cannot?(*args) !can?(*args) end |
#clear_aliased_actions ⇒ Object
Removes previously aliased actions including the defaults.
169 170 171 |
# File 'lib/cancan/ability.rb', line 169 def clear_aliased_actions @aliased_actions = {} end |