mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Create the association scope directly rather than going through with_scope
This commit is contained in:
committed by
Aaron Patterson
parent
1313d386da
commit
99a8d8430f
@@ -333,7 +333,7 @@ module ActiveRecord
|
||||
|
||||
protected
|
||||
|
||||
def construct_find_scope
|
||||
def finder_options
|
||||
{
|
||||
:conditions => construct_conditions,
|
||||
:select => construct_select,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
def construct_find_scope
|
||||
def finder_options
|
||||
{
|
||||
:conditions => construct_conditions,
|
||||
:select => @reflection.options[:select],
|
||||
|
||||
@@ -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]),
|
||||
|
||||
@@ -69,7 +69,7 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
def construct_create_scope
|
||||
def creation_attributes
|
||||
construct_owner_attributes
|
||||
end
|
||||
end
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user