passing a hash to can? will check permissions on association, this is done automatically in authorize_resource - closes #121

This commit is contained in:
Ryan Bates
2010-09-03 11:01:55 -07:00
parent 737f8acff5
commit c88cb8f459
5 changed files with 67 additions and 35 deletions

View File

@@ -21,6 +21,7 @@ module CanCan
# Matches both the subject and action, not necessarily the conditions
def relevant?(action, subject)
subject = subject.values.first if subject.kind_of? Hash
@match_all || (matches_action?(action) && matches_subject?(subject))
end
@@ -28,9 +29,11 @@ module CanCan
def matches_conditions?(action, subject, extra_args)
if @match_all
call_block_with_all(action, subject, extra_args)
elsif @block && subject.class != Class
elsif @block && !subject_class?(subject)
@block.call(subject, *extra_args)
elsif @conditions.kind_of?(Hash) && subject.class != Class
elsif @conditions.kind_of?(Hash) && subject.kind_of?(Hash)
nested_subject_matches_conditions?(subject)
elsif @conditions.kind_of?(Hash) && !subject_class?(subject)
matches_conditions_hash?(subject)
else
@base_behavior
@@ -66,6 +69,10 @@ module CanCan
private
def subject_class?(subject)
(subject.kind_of?(Hash) ? subject.values.first : subject).class == Class
end
def matches_action?(action)
@expanded_actions.include?(:manage) || @expanded_actions.include?(action)
end
@@ -95,6 +102,11 @@ module CanCan
end
end
def nested_subject_matches_conditions?(subject_hash)
parent, child = subject_hash.shift
matches_conditions_hash?(parent, @conditions[parent.class.name.downcase.to_sym])
end
def call_block_with_all(action, subject, extra_args)
if subject.class == Class
@block.call(action, subject, nil, *extra_args)

View File

@@ -32,7 +32,7 @@ module CanCan
end
def authorize_resource
@controller.authorize!(authorization_action, resource_instance || resource_class)
@controller.authorize!(authorization_action, resource_instance || resource_class_with_parent)
end
def parent?
@@ -86,6 +86,10 @@ module CanCan
end
end
def resource_class_with_parent
parent_resource ? {parent_resource => resource_class} : resource_class
end
def resource_instance
@controller.instance_variable_get("@#{instance_name}")
end
@@ -94,15 +98,15 @@ module CanCan
# If the :through option is passed it will go through an association on that instance.
# If the :singleton option is passed it won't use the association because it needs to be handled later.
def resource_base
if through_resource
@options[:singleton] ? through_resource : through_resource.send(name.to_s.pluralize)
if parent_resource
@options[:singleton] ? parent_resource : parent_resource.send(name.to_s.pluralize)
else
resource_class
end
end
# The object to load this resource through.
def through_resource
def parent_resource
@options[:through] && [@options[:through]].flatten.map { |i| @controller.instance_variable_get("@#{i}") }.compact.first
end