Permalink
Browse files

Don't construct association scope in initializer. This yields a big p…

…erformance gain for cases where the association is never used to load the target, for example with preloading. Related: #1873.
  • Loading branch information...
jonleighton committed Jul 7, 2011
1 parent a05d59f commit fe2167f3f1bcd3e673592b174e9023b70b785d02
@@ -31,7 +31,7 @@ def initialize(owner, reflection)
@updated = false
reset
- construct_scope
+ reset_scope
end
# Returns the name of the table of the related class:
@@ -52,7 +52,7 @@ def reset
# Reloads the \target and returns +self+ on success.
def reload
reset
- construct_scope
+ reset_scope
load_target
self unless target.nil?
end
@@ -85,21 +85,25 @@ def target=(target)
end
def scoped
- target_scope.merge(@association_scope)
+ target_scope.merge(association_scope)
end
- # Construct the scope for this association.
+ # The scope for this association.
#
# Note that the association_scope is merged into the target_scope only when the
# scoped method is called. This is 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
+ def association_scope
if klass
- @association_scope = AssociationScope.new(self).scope
+ @association_scope ||= AssociationScope.new(self).scope
end
end
+ def reset_scope
+ @association_scope = nil
+ end
+
# Set the inverse association, if possible
def set_inverse_instance(record)
if record && invertible_for?(record)
@@ -347,7 +347,7 @@ def save_collection_association(reflection)
end
# reconstruct the scope now that we know the owner's id
- association.send(:construct_scope) if association.respond_to?(:construct_scope)
+ association.send(:reset_scope) if association.respond_to?(:reset_scope)
end
end

0 comments on commit fe2167f

Please sign in to comment.