Skip to content

Commit

Permalink
Merge pull request #41342 from kamipo/fix_build_on_association_relation
Browse files Browse the repository at this point in the history
Fix `build` multiple records on association relation to not lose scope values
  • Loading branch information
kamipo committed Feb 5, 2021
1 parent d1fd637 commit eeb5baa
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 3 deletions.
10 changes: 10 additions & 0 deletions activerecord/lib/active_record/association_relation.rb
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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

0 comments on commit eeb5baa

Please sign in to comment.