From b17fa0c353a32c08558892f722f509f8699dba35 Mon Sep 17 00:00:00 2001
From: Isaac Betesh <iybetesh@gmail.com>
Date: Wed, 29 Mar 2017 11:05:38 -0400
Subject: Don't attempt to create a new record that was already created.

Fixes #24032
---
 .../lib/active_record/autosave_association.rb        |  5 +++++
 .../has_and_belongs_to_many_associations_test.rb     | 20 ++++++++++++++++++++
 activerecord/test/schema/schema.rb                   |  7 +++++++
 3 files changed, 32 insertions(+)

diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb
index 6bccbc06cd..607c54e481 100644
--- a/activerecord/lib/active_record/autosave_association.rb
+++ b/activerecord/lib/active_record/autosave_association.rb
@@ -181,6 +181,7 @@ module ActiveRecord
 
           if reflection.collection?
             before_save :before_save_collection_association
+            after_save :after_save_collection_association
 
             define_non_cyclic_method(save_method) { save_collection_association(reflection) }
             # Doesn't use after_save as that would save associations added in after_create/after_update twice
@@ -371,6 +372,10 @@ module ActiveRecord
         true
       end
 
+      def after_save_collection_association
+        @new_record_before_save = false
+      end
+
       # Saves any new associated records, or all loaded autosave associations if
       # <tt>:autosave</tt> is enabled on the association.
       #
diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
index d6b595d7e7..8060790594 100644
--- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
@@ -111,6 +111,21 @@ class ProjectUnscopingDavidDefaultScope < ActiveRecord::Base
     association_foreign_key: "developer_id"
 end
 
+class Kitchen < ActiveRecord::Base
+  has_one :sink
+end
+
+class Sink < ActiveRecord::Base
+  has_and_belongs_to_many :sources, join_table: :edges
+  belongs_to :kitchen
+  accepts_nested_attributes_for :kitchen
+end
+
+class Source < ActiveRecord::Base
+  self.table_name = "men"
+  has_and_belongs_to_many :sinks, join_table: :edges
+end
+
 class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
   fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects,
            :parrots, :pirates, :parrots_pirates, :treasures, :price_estimates, :tags, :taggings, :computers
@@ -1021,4 +1036,9 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
       ActiveRecord::Base.partial_writes = original_partial_writes
     end
   end
+
+  def test_has_and_belongs_to_many_with_belongs_to
+    sink = Sink.create! kitchen: Kitchen.new, sources: [Source.new]
+    assert_equal 1, sink.sources.count
+  end
 end
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index 08bef08abc..50f1d9bfe7 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -413,6 +413,9 @@ ActiveRecord::Schema.define do
     t.string      :name
   end
 
+  create_table :kitchens, force: true do |t|
+  end
+
   create_table :legacy_things, force: true do |t|
     t.integer :tps_report_number
     t.integer :version, null: false, default: 0
@@ -783,6 +786,10 @@ ActiveRecord::Schema.define do
     t.belongs_to :ship
   end
 
+  create_table :sinks, force: true do |t|
+    t.references :kitchen
+  end
+
   create_table :shop_accounts, force: true do |t|
     t.references :customer
     t.references :customer_carrier
-- 
cgit v1.2.3