aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMehmet Emin İNAÇ <mehmetemininac@gmail.com>2015-04-14 22:50:36 +0300
committerMehmet Emin İNAÇ <mehmetemininac@gmail.com>2016-02-13 17:21:25 +0200
commit9991f14fced25dac3699b473a05cc7a196f9220e (patch)
treedaace2e77f5c88e29f7e8fda85cc9cbd4b6fdcb6
parent7ee2002008eb7bd4546f556670f5332f06901a0d (diff)
downloadrails-9991f14fced25dac3699b473a05cc7a196f9220e.tar.gz
rails-9991f14fced25dac3699b473a05cc7a196f9220e.tar.bz2
rails-9991f14fced25dac3699b473a05cc7a196f9220e.zip
Fix for has_and_belongs_to_many & has_many_through associations while partial_writes is false
This will fix #19663 Also with this fix, active record does not fire unnecassary update queries while partial_writes is true
-rw-r--r--activerecord/CHANGELOG.md8
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb5
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb13
3 files changed, 24 insertions, 2 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index f13a80195a..f7fdb6755d 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,10 @@
+* Improved partial writes with HABTM and has many through associations
+ to fire database query only if relation has been changed.
+
+ Fixes #19663.
+
+ *Mehmet Emin İNAÇ*
+
* Rework `ActiveRecord::Relation#last`
1. Never perform additional SQL on loaded relation
@@ -18,7 +25,6 @@
*Bogdan Gusiev*
-
* Allow `joins` to be unscoped.
Closes #13775.
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 36fc381343..7ddb96db13 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -86,7 +86,10 @@ module ActiveRecord
end
def save_through_record(record)
- build_through_record(record).save!
+ association = build_through_record(record)
+ if association.changed?
+ association.save!
+ end
ensure
@through_records.delete(record.object_id)
end
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 5c4586da19..cab9dff6ca 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
@@ -982,4 +982,17 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
Project.first.developers_required_by_default.create!(name: "Sean", salary: 50000)
end
end
+
+ def test_has_and_belongs_to_many_while_partial_writes_false
+ begin
+ original_partial_writes = ActiveRecord::Base.partial_writes
+ ActiveRecord::Base.partial_writes = false
+ developer = Developer.new(name: "Mehmet Emin İNAÇ")
+ developer.projects << Project.new(name: "Bounty")
+
+ assert developer.save
+ ensure
+ ActiveRecord::Base.partial_writes = original_partial_writes
+ end
+ end
end