From 2e3bba3e3af8c41e833cced61f0449ad73c947cc Mon Sep 17 00:00:00 2001 From: Ryan Kerr Date: Sat, 30 Mar 2019 00:35:16 -0400 Subject: Fix callbacks on has_many :through associations (#33249) When adding a child record via a has_many :through association, build_through_record would previously build the join record, and then assign the child record and source_type option to it. Because the before_add and after_add callbacks are called as part of build, however, this caused the callbacks to receive incomplete records, specifically without the other end of the has_many :through association. Collecting all attributes before building the join record ensures the callbacks receive the fully constructed record. --- .../associations/has_many_through_association.rb | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index 84a9797aa5..b6049bdab4 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -57,21 +57,15 @@ module ActiveRecord @through_records[record.object_id] ||= begin ensure_mutable - through_record = through_association.build(*options_for_through_record) - through_record.send("#{source_reflection.name}=", record) - - if options[:source_type] - through_record.send("#{source_reflection.foreign_type}=", options[:source_type]) - end + attributes = through_scope_attributes + attributes[source_reflection.name] = record + attributes[source_reflection.foreign_type] = options[:source_type] if options[:source_type] + through_record = through_association.build(attributes) through_record end end - def options_for_through_record - [through_scope_attributes] - end - def through_scope_attributes scope.where_values_hash(through_association.reflection.name.to_s). except!(through_association.reflection.foreign_key, -- cgit v1.2.3