Method: CanCan::Ability#can?
- Defined in:
- lib/cancan/ability.rb
#can?(action, subject, attribute = nil, *extra_args) ⇒ Boolean
Check if the user has permission to perform a given action on an object.
can? :destroy, @project
You can also pass the class instead of an instance (if you don’t have one handy).
can? :create, Project
Nested resources can be passed through a hash, this way conditions which are dependent upon the association will work when using a class.
can? :create, @category => Project
You can also pass multiple objects to check. You only need to pass a hash following the pattern { :any => [many subjects] }. The behaviour is check if there is a permission on any of the given objects.
can? :create, {:any => [Project, Rule]}
Any additional arguments will be passed into the “can” block definition. This can be used to pass more information about the user’s request for example.
can? :create, Project, request.remote_ip
can :create, Project do |project, remote_ip|
# ...
end
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
Also see the RSpec Matchers to aid in testing.
74 75 76 77 78 79 80 81 |
# File 'lib/cancan/ability.rb', line 74 def can?(action, subject, attribute = nil, *extra_args) match = extract_subjects(subject).lazy.map do |a_subject| relevant_rules_for_match(action, a_subject).detect do |rule| rule.matches_conditions?(action, a_subject, attribute, *extra_args) && rule.matches_attributes?(attribute) end end.reject(&:nil?).first match ? match.base_behavior : false end |