refactoring query.joins
This commit is contained in:
@@ -3,9 +3,7 @@ module CanCan
|
||||
# it holds the information about a "can" call made on Ability and provides
|
||||
# helpful methods to determine permission checking and conditions hash generation.
|
||||
class CanDefinition # :nodoc:
|
||||
attr_reader :conditions, :block, :base_behavior
|
||||
attr_reader :block
|
||||
attr_reader :actions
|
||||
attr_reader :base_behavior, :actions
|
||||
attr_writer :expanded_actions
|
||||
|
||||
# The first argument when initializing is the base_behavior which is a true/false
|
||||
@@ -55,20 +53,12 @@ module CanCan
|
||||
@conditions == {} || @conditions.nil?
|
||||
end
|
||||
|
||||
def association_joins(conditions = @conditions)
|
||||
return nil unless conditions.kind_of?(Hash)
|
||||
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
|
||||
def associations_hash(conditions = @conditions)
|
||||
hash = {}
|
||||
conditions.map do |name, value|
|
||||
hash[name] = associations_hash(value) if value.kind_of? Hash
|
||||
end
|
||||
joins unless joins.empty?
|
||||
hash
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -32,9 +32,11 @@ module CanCan
|
||||
# Returns the associations used in conditions for the :joins option of a search
|
||||
# See ActiveRecordAdditions#accessible_by for use in Active Record.
|
||||
def joins
|
||||
unless @can_definitions.empty?
|
||||
collect_association_joins(@can_definitions)
|
||||
joins_hash = {}
|
||||
@can_definitions.each do |can_definition|
|
||||
merge_joins(joins_hash, can_definition.associations_hash)
|
||||
end
|
||||
clean_joins(joins_hash) unless joins_hash.empty?
|
||||
end
|
||||
|
||||
private
|
||||
@@ -67,31 +69,22 @@ module CanCan
|
||||
@sanitizer.sanitize_sql(conditions)
|
||||
end
|
||||
|
||||
def collect_association_joins(can_definitions)
|
||||
joins = []
|
||||
@can_definitions.each do |can_definition|
|
||||
merge_association_joins(joins, can_definition.association_joins || [])
|
||||
end
|
||||
joins = clear_association_joins(joins)
|
||||
joins unless joins.empty?
|
||||
end
|
||||
|
||||
def merge_association_joins(what, with)
|
||||
with.each do |join|
|
||||
name, nested = join.each_pair.first
|
||||
if at = what.detect{|h| h.has_key?(name) }
|
||||
at[name] = merge_association_joins(at[name], nested)
|
||||
def merge_joins(base, add)
|
||||
add.each do |name, nested|
|
||||
if base[name].is_a?(Hash) && !nested.empty?
|
||||
merge_joins(base[name], nested)
|
||||
else
|
||||
what << join
|
||||
base[name] = nested
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def clear_association_joins(joins)
|
||||
joins.map do |join|
|
||||
name, nested = join.each_pair.first
|
||||
nested.empty? ? name : {name => clear_association_joins(nested)}
|
||||
def clean_joins(joins_hash)
|
||||
joins = []
|
||||
joins_hash.each do |name, nested|
|
||||
joins << (nested.empty? ? name : {name => clean_joins(nested)})
|
||||
end
|
||||
joins
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user