From 99a8d8430f9b819cd3e8cb3aab44cb04ea402532 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Mon, 3 Jan 2011 12:04:33 +0000 Subject: Create the association scope directly rather than going through with_scope --- .../associations/association_collection.rb | 2 +- .../associations/association_proxy.rb | 36 ++++++++++++---------- .../associations/belongs_to_association.rb | 2 +- .../has_and_belongs_to_many_association.rb | 2 +- .../associations/has_many_association.rb | 2 +- .../associations/has_one_association.rb | 4 +-- .../associations/through_association.rb | 15 ++++----- 7 files changed, 32 insertions(+), 31 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 6defc465d8..4bd8a8e2d2 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -333,7 +333,7 @@ module ActiveRecord protected - def construct_find_scope + def finder_options { :conditions => construct_conditions, :select => construct_select, diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb index ab42d0f215..3a0cda49f8 100644 --- a/activerecord/lib/active_record/associations/association_proxy.rb +++ b/activerecord/lib/active_record/associations/association_proxy.rb @@ -169,7 +169,9 @@ module ActiveRecord end def scoped - with_scope(@scope) { target_klass.scoped } + target_scope. + apply_finder_options(@finder_options). + create_with(@creation_attributes) end protected @@ -182,30 +184,26 @@ module ActiveRecord @reflection.klass.send(:sanitize_sql, sql, table_name) end - # Forwards +with_scope+ to the reflection. - def with_scope(*args, &block) - target_klass.send :with_scope, *args, &block - end - - # Construct the scope used for find/create queries on the target + # Construct the data used for the scope for this association + # + # Note that we don't actually build the scope here, we just construct the options and + # attributes. We must only build the scope when it's actually needed, because at that + # point the call may be surrounded by scope.scoping { ... } or with_scope { ... } etc, + # which affects the scope which actually gets built. def construct_scope if target_klass - @scope = { - :find => construct_find_scope, - :create => construct_create_scope - } - else - @scope = nil + @finder_options = finder_options + @creation_attributes = creation_attributes end end # Implemented by subclasses - def construct_find_scope + def finder_options raise NotImplementedError end # Implemented by (some) subclasses - def construct_create_scope + def creation_attributes {} end @@ -226,6 +224,12 @@ module ActiveRecord @reflection.klass end + # Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the + # through association's scope) + def target_scope + target_klass.scoped + end + private # Forwards any missing method call to the \target. def method_missing(method, *args) @@ -256,7 +260,7 @@ module ActiveRecord def load_target return nil unless defined?(@loaded) - if !loaded? && (!@owner.new_record? || foreign_key_present?) && @scope + if !loaded? && (!@owner.new_record? || foreign_key_present?) && target_klass @target = find_target end diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index 98b846f97c..4cde1c0960 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -60,7 +60,7 @@ module ActiveRecord end end - def construct_find_scope + def finder_options { :conditions => construct_conditions, :select => @reflection.options[:select], diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index 3abe3c2dae..1c237eda33 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -79,7 +79,7 @@ module ActiveRecord super(join_table) end - def construct_find_scope + def finder_options super.merge( :joins => construct_joins, :readonly => ambiguous_select?(@reflection.options[:select]), diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index 2060f1ff62..dba26a78da 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -69,7 +69,7 @@ module ActiveRecord end end - def construct_create_scope + def creation_attributes construct_owner_attributes end end diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index 0070606c24..5716bef524 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -68,7 +68,7 @@ module ActiveRecord scoped.first.tap { |record| set_inverse_instance(record) } end - def construct_find_scope + def finder_options { :conditions => construct_conditions, :select => @reflection.options[:select], @@ -78,7 +78,7 @@ module ActiveRecord } end - def construct_create_scope + def creation_attributes construct_owner_attributes end diff --git a/activerecord/lib/active_record/associations/through_association.rb b/activerecord/lib/active_record/associations/through_association.rb index b2f1f941c0..65c36419da 100644 --- a/activerecord/lib/active_record/associations/through_association.rb +++ b/activerecord/lib/active_record/associations/through_association.rb @@ -3,16 +3,13 @@ module ActiveRecord module Associations module ThroughAssociation - def scoped - with_scope(@scope) do - @reflection.klass.scoped & - @reflection.through_reflection.klass.scoped - end - end - protected - def construct_find_scope + def target_scope + super & @reflection.through_reflection.klass.scoped + end + + def finder_options super.merge( :joins => construct_joins, :include => @reflection.options[:include] || @@ -24,7 +21,7 @@ module ActiveRecord # moment we only support creating on a :through association when the source reflection is a # belongs_to. Thus it's not necessary to set a foreign key on the associated record(s), so # this scope has can legitimately be empty. - def construct_create_scope + def creation_attributes { } end -- cgit v1.2.3