From dc16cdd89a93817203e7c8a49af174fde81402e0 Mon Sep 17 00:00:00 2001 From: Alireza Bashiri Date: Fri, 27 Jul 2018 11:20:45 +0430 Subject: [PATCH] Call build when extend with nested attributes defined What? From now on when `accepts_nested_attributes_for` defined and `extend` option added the overwritten `build` method being called. [Alireza Bashiri, Martins Polakovs] --- activerecord/lib/active_record/nested_attributes.rb | 2 +- activerecord/test/cases/nested_attributes_test.rb | 12 ++++++++++++ activerecord/test/models/pirate.rb | 8 +++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb index fa20bce3a9..50767ee93f 100644 --- a/activerecord/lib/active_record/nested_attributes.rb +++ b/activerecord/lib/active_record/nested_attributes.rb @@ -501,7 +501,7 @@ module ActiveRecord if attributes["id"].blank? unless reject_new_record?(association_name, attributes) - association.build(attributes.except(*UNASSIGNABLE_KEYS)) + association.reader.build(attributes.except(*UNASSIGNABLE_KEYS)) end elsif existing_record = existing_records.detect { |record| record.id.to_s == attributes["id"].to_s } unless call_reject_if(association_name, attributes) diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index ec01a2965d..aa519fd332 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -1094,3 +1094,15 @@ class TestHasManyAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveR assert_equal ["Ship name can't be blank"], part.errors.full_messages end end + +class TestNestedAttributesWithExtend < ActiveRecord::TestCase + setup do + Pirate.accepts_nested_attributes_for :treasures + end + + def test_extend_affects_nested_attributes + pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?") + pirate.treasures_attributes = [{ id: nil }] + assert_equal "from extension", pirate.treasures[0].name + end +end diff --git a/activerecord/test/models/pirate.rb b/activerecord/test/models/pirate.rb index c8617d1cfe..fd5083e597 100644 --- a/activerecord/test/models/pirate.rb +++ b/activerecord/test/models/pirate.rb @@ -17,7 +17,13 @@ class Pirate < ActiveRecord::Base after_remove: proc { |p, pa| p.ship_log << "after_removing_proc_parrot_#{pa.id}" } has_and_belongs_to_many :autosaved_parrots, class_name: "Parrot", autosave: true - has_many :treasures, as: :looter + module PostTreasuresExtension + def build(attributes = {}) + super({ name: "from extension" }.merge(attributes)) + end + end + + has_many :treasures, as: :looter, extend: PostTreasuresExtension has_many :treasure_estimates, through: :treasures, source: :price_estimates has_one :ship