aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2011-01-03 12:04:33 +0000
committerAaron Patterson <aaron.patterson@gmail.com>2011-01-03 16:24:32 -0800
commit99a8d8430f9b819cd3e8cb3aab44cb04ea402532 (patch)
tree0879c76ed6700a985ac68108cc6929622981e5f2 /activerecord/lib/active_record/associations
parent1313d386dacb580858e5951418a637f4e17cf5c1 (diff)
downloadrails-99a8d8430f9b819cd3e8cb3aab44cb04ea402532.tar.gz
rails-99a8d8430f9b819cd3e8cb3aab44cb04ea402532.tar.bz2
rails-99a8d8430f9b819cd3e8cb3aab44cb04ea402532.zip
Create the association scope directly rather than going through with_scope
Diffstat (limited to 'activerecord/lib/active_record/associations')
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb2
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb36
-rw-r--r--activerecord/lib/active_record/associations/belongs_to_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/has_many_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/has_one_association.rb4
-rw-r--r--activerecord/lib/active_record/associations/through_association.rb15
7 files changed, 32 insertions, 31 deletions
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