Skip to content

Commit

Permalink
Memoize through association
Browse files Browse the repository at this point in the history
  • Loading branch information
jonleighton committed Nov 3, 2011
1 parent 19b2a5f commit 567d454
Showing 1 changed file with 11 additions and 8 deletions.
Expand Up @@ -8,7 +8,9 @@ class HasManyThroughAssociation < HasManyAssociation #:nodoc:

def initialize(owner, reflection)
super
@through_records = {}

@through_records = {}
@through_association = nil
end

# Returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn't been
Expand Down Expand Up @@ -55,7 +57,7 @@ def insert_record(record, validate = true, raise = false)
private

def through_association
owner.association(through_reflection.name)
@through_association ||= owner.association(through_reflection.name)
end

# We temporarily cache through record that has been build, because if we build a
Expand Down Expand Up @@ -118,8 +120,7 @@ def update_through_counter?(method)
def delete_records(records, method)
ensure_not_nested

through = through_association
scope = through.scoped.where(construct_join_attributes(*records))
scope = through_association.scoped.where(construct_join_attributes(*records))

case method
when :destroy
Expand All @@ -130,7 +131,7 @@ def delete_records(records, method)
count = scope.delete_all
end

delete_through_records(through, records)
delete_through_records(records)

if through_reflection.macro == :has_many && update_through_counter?(method)
update_counter(-count, through_reflection)
Expand All @@ -145,14 +146,16 @@ def through_records_for(record)
candidates.find_all { |c| c.attributes.slice(*attributes.keys) == attributes }
end

def delete_through_records(through, records)
def delete_through_records(records)
records.each do |record|
through_records = through_records_for(record)

if through_reflection.macro == :has_many
through_records.each { |r| through.target.delete(r) }
through_records.each { |r| through_association.target.delete(r) }
else
through.target = nil if through_records.include?(through.target)
if through_records.include?(through_association.target)
through_association.target = nil
end
end

@through_records.delete(record.object_id)
Expand Down

0 comments on commit 567d454

Please sign in to comment.