Skip to content
Browse files

Create the association scope directly rather than going through with_…

…scope
  • Loading branch information...
1 parent 1313d38 commit 99a8d8430f9b819cd3e8cb3aab44cb04ea402532 @jonleighton jonleighton committed with tenderlove Jan 3, 2011
View
2 activerecord/lib/active_record/associations/association_collection.rb
@@ -333,7 +333,7 @@ def proxy_respond_to?(method, include_private = false)
protected
- def construct_find_scope
+ def finder_options
{
:conditions => construct_conditions,
:select => construct_select,
View
36 activerecord/lib/active_record/associations/association_proxy.rb
@@ -169,7 +169,9 @@ def send(method, *args)
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 @@ def sanitize_sql(sql, table_name = @reflection.klass.table_name)
@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 @@ def target_klass
@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 @@ def method_missing(method, *args)
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
View
2 activerecord/lib/active_record/associations/belongs_to_association.rb
@@ -60,7 +60,7 @@ def find_target
end
end
- def construct_find_scope
+ def finder_options
{
:conditions => construct_conditions,
:select => @reflection.options[:select],
View
2 activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
@@ -79,7 +79,7 @@ def construct_owner_conditions
super(join_table)
end
- def construct_find_scope
+ def finder_options
super.merge(
:joins => construct_joins,
:readonly => ambiguous_select?(@reflection.options[:select]),
View
2 activerecord/lib/active_record/associations/has_many_association.rb
@@ -69,7 +69,7 @@ def delete_records(records)
end
end
- def construct_create_scope
+ def creation_attributes
construct_owner_attributes
end
end
View
4 activerecord/lib/active_record/associations/has_one_association.rb
@@ -68,7 +68,7 @@ def find_target
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 @@ def construct_find_scope
}
end
- def construct_create_scope
+ def creation_attributes
construct_owner_attributes
end
View
15 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 @@ def construct_find_scope
# 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

0 comments on commit 99a8d84

Please sign in to comment.
Something went wrong with that request. Please try again.