aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorRafael Mendonça França <rafaelmfranca@gmail.com>2012-08-10 09:25:33 -0700
committerRafael Mendonça França <rafaelmfranca@gmail.com>2012-08-10 15:05:02 -0300
commit2e000743801359c37e80cb2cc68ef5c4721ef780 (patch)
tree6123e5980b18e0beab423c16a370c0a24cf04f06 /activerecord
parentae2383d90a9646e36c8b5d92801fba284ea62ec0 (diff)
downloadrails-2e000743801359c37e80cb2cc68ef5c4721ef780.tar.gz
rails-2e000743801359c37e80cb2cc68ef5c4721ef780.tar.bz2
rails-2e000743801359c37e80cb2cc68ef5c4721ef780.zip
Merge pull request #7286 from kennyj/fix_7191
Fix #7191. Remove unnecessary transaction when assigning has_one associations. Conflicts: activerecord/test/cases/associations/has_one_associations_test.rb
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/associations/has_one_association.rb28
-rw-r--r--activerecord/test/cases/associations/has_one_associations_test.rb13
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 f0d1120c68..08f66eed3f 100644
--- a/activerecord/lib/active_record/associations/has_one_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_association.rb
@@ -8,19 +8,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 3ce87df126..08831a42ba 100644
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -472,4 +472,17 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
assert_equal car.id, bulb.attributes_after_initialize['car_id']
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