aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/reflection.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/reflection.rb')
-rw-r--r--activerecord/lib/active_record/reflection.rb45
1 files changed, 22 insertions, 23 deletions
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 0d9534acd6..3e8d9718f5 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -20,9 +20,9 @@ module ActiveRecord
# MacroReflection class has info for the AssociationReflection
# class.
module ClassMethods
- def create_reflection(macro, name, options, active_record)
+ def create_reflection(macro, name, scope, options, active_record)
klass = options[:through] ? ThroughReflection : AssociationReflection
- reflection = klass.new(macro, name, options, active_record)
+ reflection = klass.new(macro, name, scope, options, active_record)
self.reflections = self.reflections.merge(name => reflection)
reflection
@@ -71,6 +71,8 @@ module ActiveRecord
# <tt>has_many :clients</tt> returns <tt>:has_many</tt>
attr_reader :macro
+ attr_reader :scope
+
# Returns the hash of options used for the macro.
#
# <tt>has_many :clients</tt> returns +{}+
@@ -80,9 +82,10 @@ module ActiveRecord
attr_reader :plural_name # :nodoc:
- def initialize(macro, name, options, active_record)
+ def initialize(macro, name, scope, options, active_record)
@macro = macro
@name = name
+ @scope = scope
@options = options
@active_record = active_record
@plural_name = active_record.pluralize_table_names ?
@@ -142,7 +145,7 @@ module ActiveRecord
@klass ||= active_record.send(:compute_type, class_name)
end
- def initialize(macro, name, options, active_record)
+ def initialize(*args)
super
@collection = [:has_many, :has_and_belongs_to_many].include?(macro)
end
@@ -244,11 +247,10 @@ module ActiveRecord
false
end
- # An array of arrays of conditions. Each item in the outside array corresponds to a reflection
- # in the #chain. The inside arrays are simply conditions (and each condition may itself be
- # a hash, array, arel predicate, etc...)
- def conditions
- [[options[:conditions]].compact]
+ # An array of arrays of scopes. Each item in the outside array corresponds to a reflection
+ # in the #chain.
+ def scope_chain
+ scope ? [[scope]] : [[]]
end
alias :source_macro :macro
@@ -416,28 +418,25 @@ module ActiveRecord
# has_many :tags
# end
#
- # There may be conditions on Person.comment_tags, Article.comment_tags and/or Comment.tags,
+ # There may be scopes on Person.comment_tags, Article.comment_tags and/or Comment.tags,
# but only Comment.tags will be represented in the #chain. So this method creates an array
- # of conditions corresponding to the chain. Each item in the #conditions array corresponds
- # to an item in the #chain, and is itself an array of conditions from an arbitrary number
- # of relevant reflections, plus any :source_type or polymorphic :as constraints.
- def conditions
- @conditions ||= begin
- conditions = source_reflection.conditions.map { |c| c.dup }
+ # of scopes corresponding to the chain.
+ def scope_chain
+ @scope_chain ||= begin
+ scope_chain = source_reflection.scope_chain.map(&:dup)
- # Add to it the conditions from this reflection if necessary.
- conditions.first << options[:conditions] if options[:conditions]
+ # Add to it the scope from this reflection (if any)
+ scope_chain.first << scope if scope
- through_conditions = through_reflection.conditions
+ through_scope_chain = through_reflection.scope_chain
if options[:source_type]
- through_conditions.first << { foreign_type => options[:source_type] }
+ through_scope_chain.first <<
+ through_reflection.klass.where(foreign_type => options[:source_type])
end
# Recursively fill out the rest of the array from the through reflection
- conditions += through_conditions
-
- conditions
+ scope_chain + through_scope_chain
end
end