diff options
-rw-r--r-- | activerecord/CHANGELOG | 2 | ||||
-rwxr-xr-x | activerecord/lib/active_record/associations.rb | 13 | ||||
-rwxr-xr-x | activerecord/test/cases/associations_test.rb | 12 |
3 files changed, 27 insertions, 0 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 90173a4bc1..cb8b4ceaca 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Ensure that save on parent object fails for invalid has_one association. Closes #10518. [Pratik] + * Remove duplicate code from associations. [Pratik] * Refactor HasManyThroughAssociation to inherit from HasManyAssociation. Association callbacks and <association>_ids= now work with hm:t. #11516 [rubyruy] diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 0acc63bd69..7d27b0607a 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -784,6 +784,7 @@ module ActiveRecord end after_save method_name + add_single_associated_save_callbacks(reflection.name) association_accessor_methods(reflection, HasOneAssociation) association_constructor_method(:build, reflection, HasOneAssociation) association_constructor_method(:create, reflection, HasOneAssociation) @@ -1141,6 +1142,18 @@ module ActiveRecord end end + def add_single_associated_save_callbacks(association_name) + method_name = "validate_associated_records_for_#{association_name}".to_sym + define_method(method_name) do + association = instance_variable_get("@#{association_name}") + if !association.nil? + errors.add "#{association_name}" unless association.target.nil? || association.valid? + end + end + + validate method_name + end + def add_multiple_associated_save_callbacks(association_name) method_name = "validate_associated_records_for_#{association_name}".to_sym ivar = "@#{association_name}" diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb index 22a6bfc3a5..6aa9010f48 100755 --- a/activerecord/test/cases/associations_test.rb +++ b/activerecord/test/cases/associations_test.rb @@ -433,6 +433,18 @@ class HasOneAssociationsTest < ActiveRecord::TestCase assert_equal a, firm.account assert_equal a, firm.account(true) end + + def test_save_fails_for_invalid_has_one + firm = Firm.find(:first) + assert firm.valid? + + firm.account = Account.new + + assert !firm.account.valid? + assert !firm.valid? + assert !firm.save + assert_equal "is invalid", firm.errors.on("account") + end def test_assignment_before_either_saved firm = Firm.new("name" => "GlobalMegaCorp") |