adding joins clause to accessible_by when conditions are across associations

This commit is contained in:
Ryan Bates
2010-04-20 17:02:28 -07:00
parent 4da31c0709
commit e20081454f
6 changed files with 68 additions and 7 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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