adding joins clause to accessible_by when conditions are across associations
This commit is contained in:
@@ -200,6 +200,16 @@ module CanCan
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the associations used in conditions. This is usually used in the :joins option for a search.
|
||||
# See ActiveRecordAdditions#accessible_by for use in Active Record.
|
||||
def association_joins(action, subject)
|
||||
can_definition = matching_can_definition(action, subject)
|
||||
if can_definition
|
||||
raise Error, "Cannot determine association joins from block for #{action.inspect} #{subject.inspect}" if can_definition.block
|
||||
can_definition.association_joins
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def can_definitions
|
||||
|
||||
@@ -21,10 +21,11 @@ module CanCan
|
||||
# internally uses Ability#conditions method, see that for more information.
|
||||
def accessible_by(ability, action = :read)
|
||||
conditions = ability.conditions(action, self) || {:id => nil}
|
||||
joins = ability.association_joins(action, self)
|
||||
if respond_to? :where
|
||||
where(conditions)
|
||||
where(conditions).joins(joins)
|
||||
else
|
||||
scoped(:conditions => conditions)
|
||||
scoped(:conditions => conditions, :joins => joins)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -25,6 +25,21 @@ module CanCan
|
||||
result = can_without_base_behavior?(action, subject, extra_args)
|
||||
@base_behavior ? result : !result
|
||||
end
|
||||
|
||||
def association_joins(conditions = @conditions)
|
||||
joins = []
|
||||
conditions.each do |name, value|
|
||||
if value.kind_of? Hash
|
||||
nested = association_joins(value)
|
||||
if nested
|
||||
joins << {name => nested}
|
||||
else
|
||||
joins << name
|
||||
end
|
||||
end
|
||||
end
|
||||
joins unless joins.empty?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
||||
Reference in New Issue
Block a user