Skip to content

Commit

Permalink
Merge pull request #42524 from ghiculescu/has-many-build-perf-regression
Browse files Browse the repository at this point in the history
Performance regression in CollectionAssocation#build
  • Loading branch information
rafaelfranca committed Oct 13, 2021
1 parent 0e4e64d commit fb460a4
Showing 1 changed file with 11 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def ids_writer(ids)
def reset
super
@target = []
@replaced_targets = Set.new
@association_ids = nil
end

Expand Down Expand Up @@ -279,10 +280,7 @@ def load_target
end

def add_to_target(record, skip_callbacks: false, replace: false, &block)
if replace || association_scope.distinct_value
index = @target.index(record)
end
replace_on_target(record, index, skip_callbacks, &block)
replace_on_target(record, skip_callbacks, replace: replace || association_scope.distinct_value, &block)
end

def target=(record)
Expand All @@ -292,7 +290,7 @@ def target=(record)
when Array
super
else
add_to_target(record, skip_callbacks: true, replace: true)
replace_on_target(record, true, replace: true, inversing: true)
end
end

Expand Down Expand Up @@ -425,7 +423,7 @@ def replace_common_records_in_memory(new_target, original_target)
common_records = intersection(new_target, original_target)
common_records.each do |record|
skip_callbacks = true
replace_on_target(record, @target.index(record), skip_callbacks)
replace_on_target(record, skip_callbacks, replace: true)
end
end

Expand All @@ -448,7 +446,11 @@ def concat_records(records, raise = false)
records
end

def replace_on_target(record, index, skip_callbacks)
def replace_on_target(record, skip_callbacks, replace:, inversing: false)
if replace && (!record.new_record? || @replaced_targets.include?(record))
index = @target.index(record)
end

catch(:abort) do
callback(:before_add, record)
end || return unless skip_callbacks
Expand All @@ -459,6 +461,8 @@ def replace_on_target(record, index, skip_callbacks)

yield(record) if block_given?

@replaced_targets << record if inversing || index

if index
target[index] = record
elsif @_was_loaded || !loaded?
Expand Down

0 comments on commit fb460a4

Please sign in to comment.