From 4fef7c2a56ee183e720e634bd23d674f46949c1a Mon Sep 17 00:00:00 2001 From: eileencodes <eileencodes@gmail.com> Date: Mon, 30 Jan 2017 14:11:53 -0500 Subject: Implement `scopes` method on each Reflection Each reflection should be responsible for returning the scopes needed to query against the db. --- activerecord/lib/active_record/reflection.rb | 52 +++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 5 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 2c8c4b6297..face8e9200 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -175,6 +175,10 @@ module ActiveRecord JoinKeys.new(foreign_key, active_record_primary_key) end + def scopes + scope ? [scope] : [] + end + def constraints scope_chain.flatten end @@ -815,6 +819,40 @@ module ActiveRecord # 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 scopes corresponding to the chain. + def scopes + @sc ||= if scope + source_reflection.scopes + through_reflection.scopes + [scope] + else + source_reflection.scopes + through_reflection.scopes + end + + return @sc + scope_chain = source_reflection.scopes + scope_chain = through_reflection.scopes + + # Add to it the scope from this reflection (if any) + scope_chain.first << scope if scope + + through_scope_chain = through_reflection.scope_chain.map(&:dup) + + if options[:source_type] + through_scope_chain.first << source_type_lambda + end + + # Recursively fill out the rest of the array from the through reflection + scope_chain + through_scope_chain + end + + def source_type_lambda + @source_type_lambda ||= begin + type = foreign_type + source_type = options[:source_type] + lambda { |object| + where(type => source_type) + } + end + end + def scope_chain @scope_chain ||= begin scope_chain = source_reflection.scope_chain.map(&:dup) @@ -825,11 +863,7 @@ module ActiveRecord through_scope_chain = through_reflection.scope_chain.map(&:dup) if options[:source_type] - type = foreign_type - source_type = options[:source_type] - through_scope_chain.first << lambda { |object| - where(type => source_type) - } + through_scope_chain.first << source_type_lambda end # Recursively fill out the rest of the array from the through reflection @@ -1008,6 +1042,14 @@ module ActiveRecord @previous_reflection = previous_reflection end + def scopes + if @previous_reflection.options[:source_type] + return super + [@previous_reflection.source_type_lambda] + else + return super + end + end + def klass @reflection.klass end -- cgit v1.2.3