diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index 2a961995da124..7dd0c7ba4c007 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -42,7 +42,7 @@ def delete(method = options[:dependent]) def replace(record, save = true) raise_on_type_mismatch!(record) if record - return target unless load_target || record + return target unless record || load_target assigning_another_record = target != record if assigning_another_record || record.has_changes_to_save? diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb index f9cbfebe0efef..ef05a0e47e481 100644 --- a/activerecord/test/cases/associations/has_one_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_associations_test.rb @@ -88,6 +88,14 @@ def test_proxy_assignment assert_nothing_raised { company.account = company.account } end + def test_proxy_assignment_from_hash + company = companies(:first_firm) + company_from_hash = Company.new(company.attributes) + attrs = company.account.attributes + sql = capture_sql { company_from_hash.account = Account.new(attrs) } + assert_equal [], sql + end + def test_type_mismatch assert_raise(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = 1 } assert_raise(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = Project.find(1) }