Merge pull request #42524 from ghiculescu/has-many-build-perf-regression

Performance regression in CollectionAssocation#build
This commit is contained in:
Rafael França 2021-06-17 15:38:48 -04:00 committed by GitHub
commit 9ceb940375
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 11 additions and 7 deletions

View File

@ -79,6 +79,7 @@ module ActiveRecord
def reset
super
@target = []
@replaced_targets = Set.new
@association_ids = nil
end
@ -268,10 +269,7 @@ module ActiveRecord
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)
@ -281,7 +279,7 @@ module ActiveRecord
when Array
super
else
add_to_target(record, skip_callbacks: true, replace: true)
replace_on_target(record, true, replace: true, inversing: true)
end
end
@ -418,7 +416,7 @@ module ActiveRecord
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
@ -441,7 +439,11 @@ module ActiveRecord
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
@ -452,6 +454,8 @@ module ActiveRecord
yield(record) if block_given?
@replaced_targets << record if inversing || index
if index
target[index] = record
elsif @_was_loaded || !loaded?