Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix build multiple records on association relation to not lose scope values #41342

Merged
merged 1 commit into from Feb 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions activerecord/lib/active_record/association_relation.rb
Expand Up @@ -27,6 +27,16 @@ def #{method}(attributes, **kwargs)
RUBY
end

def build(attributes = nil, &block)
if attributes.is_a?(Array)
attributes.collect { |attr| build(attr, &block) }
else
block = current_scope_restoring_block(&block)
scoping { _new(attributes, &block) }
end
end
alias new build

private
def _new(attributes, &block)
@association.build(attributes, &block)
Expand Down
50 changes: 47 additions & 3 deletions activerecord/test/cases/associations/has_many_associations_test.rb
Expand Up @@ -374,14 +374,58 @@ def test_building_the_associated_object_with_an_unrelated_type
assert_raise(ActiveRecord::SubclassNotFound) { firm.companies.build(type: "Account") }
end

test "building the association with an array" do
test "build the association with an array" do
speedometer = Speedometer.new(speedometer_id: "a")
data = [{ name: "first" }, { name: "second" }]
speedometer.minivans.build(data)
speedometer.minivans.where(color: "blue").build(data)

assert_equal 2, speedometer.minivans.size
assert speedometer.save
assert_equal ["first", "second"], speedometer.reload.minivans.map(&:name)

speedometer.reload

assert_equal ["first", "second"], speedometer.minivans.map(&:name)
assert_equal ["blue", "blue"], speedometer.minivans.map(&:color)
end

test "new the association with an array" do
speedometer = Speedometer.new(speedometer_id: "a")
data = [{ name: "first" }, { name: "second" }]
speedometer.minivans.where(color: "blue").new(data)

assert_equal 2, speedometer.minivans.size
assert speedometer.save

speedometer.reload

assert_equal ["first", "second"], speedometer.minivans.map(&:name)
assert_equal ["blue", "blue"], speedometer.minivans.map(&:color)
end

test "create the association with an array" do
speedometer = Speedometer.create!(speedometer_id: "a")
data = [{ name: "first" }, { name: "second" }]
speedometer.minivans.where(color: "blue").create(data)

assert_equal 2, speedometer.minivans.size

speedometer.reload

assert_equal ["first", "second"], speedometer.minivans.map(&:name)
assert_equal ["blue", "blue"], speedometer.minivans.map(&:color)
end

test "create! the association with an array" do
speedometer = Speedometer.create!(speedometer_id: "a")
data = [{ name: "first" }, { name: "second" }]
speedometer.minivans.where(color: "blue").create!(data)

assert_equal 2, speedometer.minivans.size

speedometer.reload

assert_equal ["first", "second"], speedometer.minivans.map(&:name)
assert_equal ["blue", "blue"], speedometer.minivans.map(&:color)
end

def test_association_keys_bypass_attribute_protection
Expand Down