diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2012-08-10 09:25:33 -0700 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2012-08-10 09:25:33 -0700 |
commit | d1835db6b5efce31af935aa804c7b537e14764d2 (patch) | |
tree | 92e4c183eec884335dd5bd8c227af143e16dad9f /activerecord | |
parent | 0b11dbe2fe6d640d0cbaec9a2d2886fb384a8c5b (diff) | |
parent | 42dd5d9f2976677a4bf22347f2dde1a8135dfbb4 (diff) | |
download | rails-d1835db6b5efce31af935aa804c7b537e14764d2.tar.gz rails-d1835db6b5efce31af935aa804c7b537e14764d2.tar.bz2 rails-d1835db6b5efce31af935aa804c7b537e14764d2.zip |
Merge pull request #7286 from kennyj/fix_7191
Fix #7191. Remove unnecessary transaction when assigning has_one associations.
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/lib/active_record/associations/has_one_association.rb | 28 | ||||
-rw-r--r-- | activerecord/test/cases/associations/has_one_associations_test.rb | 13 |
2 files changed, 28 insertions, 13 deletions
diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index 191c4e8e39..3b96ca5eb8 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -7,19 +7,21 @@ module ActiveRecord raise_on_type_mismatch(record) if record load_target - reflection.klass.transaction do - if target && target != record - remove_target!(options[:dependent]) unless target.destroyed? - end - - if record - set_owner_attributes(record) - set_inverse_instance(record) - - if owner.persisted? && save && !record.save - nullify_owner_attributes(record) - set_owner_attributes(target) if target - raise RecordNotSaved, "Failed to save the new associated #{reflection.name}." + # If target and record are nil, or target is equal to record, + # we don't need to have transaction. + if (target || record) && target != record + reflection.klass.transaction do + remove_target!(options[:dependent]) if target && !target.destroyed? + + if record + set_owner_attributes(record) + set_inverse_instance(record) + + if owner.persisted? && save && !record.save + nullify_owner_attributes(record) + set_owner_attributes(target) if target + raise RecordNotSaved, "Failed to save the new associated #{reflection.name}." + end end end end diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb index 112735839f..752c33b1db 100644 --- a/activerecord/test/cases/associations/has_one_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_associations_test.rb @@ -535,4 +535,17 @@ class HasOneAssociationsTest < ActiveRecord::TestCase ensure ActiveRecord::Base.dependent_restrict_raises = option_before end + + def test_has_one_transaction + company = companies(:first_firm) + account = Account.find(1) + + company.account # force loading + assert_no_queries { company.account = account } + + company.account = nil + assert_no_queries { company.account = nil } + account = Account.find(2) + assert_queries { company.account = account } + end end |