From d45c9adf272ce749f76ba2dcfaa2745b5f877daa Mon Sep 17 00:00:00 2001 From: Gannon McGibbon Date: Mon, 26 Nov 2018 13:04:32 -0500 Subject: [PATCH] Add support for belongs_to to has_many inversing. --- activerecord/CHANGELOG.md | 4 ++++ .../associations/belongs_to_association.rb | 5 +---- .../associations/collection_association.rb | 9 +++++++++ .../cases/associations/inverse_associations_test.rb | 12 ++++++------ 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 53d64334e7..182460d4d8 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,7 @@ +* Add support for `belongs_to` to `has_many` inversing. + + *Gannon McGibbon* + * Allow length configuration for `has_secure_token` method. The minimum length is set at 24 characters. diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index e3886f394a..67591dd0dc 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -108,11 +108,8 @@ module ActiveRecord owner._read_attribute(reflection.foreign_key) end - # NOTE - for now, we're only supporting inverse setting from belongs_to back onto - # has_one associations. def invertible_for?(record) - inverse = inverse_reflection_for(record) - inverse && inverse.has_one? + inverse_reflection_for(record) end def stale_state diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb index 891b50d160..f1b470f97e 100644 --- a/activerecord/lib/active_record/associations/collection_association.rb +++ b/activerecord/lib/active_record/associations/collection_association.rb @@ -285,6 +285,15 @@ module ActiveRecord replace_on_target(record, index, skip_callbacks, &block) end + def target=(record) + case record + when Array + super + else + add_to_target(record) + end + end + def scope scope = super scope.none! if null_scope? diff --git a/activerecord/test/cases/associations/inverse_associations_test.rb b/activerecord/test/cases/associations/inverse_associations_test.rb index 669e176dcb..6a18c56e3f 100644 --- a/activerecord/test/cases/associations/inverse_associations_test.rb +++ b/activerecord/test/cases/associations/inverse_associations_test.rb @@ -607,7 +607,7 @@ class InverseBelongsToTests < ActiveRecord::TestCase assert_equal f.description, m.face.description, "Description of face should be the same after changes to newly-created-parent-owned instance" end - def test_should_not_try_to_set_inverse_instances_when_the_inverse_is_a_has_many + def test_should_try_to_set_inverse_instances_when_the_inverse_is_a_has_many i = interests(:trainspotting) m = i.man assert_not_nil m.interests @@ -615,9 +615,9 @@ class InverseBelongsToTests < ActiveRecord::TestCase assert_not_nil iz assert_equal i.topic, iz.topic, "Interest topics should be the same before changes to child" i.topic = "Eating cheese with a spoon" - assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to child" + assert_equal i.topic, iz.topic, "Interest topics should be the same after changes to child" iz.topic = "Cow tipping" - assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to parent-owned instance" + assert_equal i.topic, iz.topic, "Interest topics should be the same after changes to parent-owned instance" end def test_child_instance_should_be_shared_with_replaced_via_accessor_parent @@ -704,7 +704,7 @@ class InversePolymorphicBelongsToTests < ActiveRecord::TestCase assert_equal old_inversed_man.object_id, new_inversed_man.object_id end - def test_should_not_try_to_set_inverse_instances_when_the_inverse_is_a_has_many + def test_should_try_to_set_inverse_instances_when_the_inverse_is_a_has_many i = interests(:llama_wrangling) m = i.polymorphic_man assert_not_nil m.polymorphic_interests @@ -712,9 +712,9 @@ class InversePolymorphicBelongsToTests < ActiveRecord::TestCase assert_not_nil iz assert_equal i.topic, iz.topic, "Interest topics should be the same before changes to child" i.topic = "Eating cheese with a spoon" - assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to child" + assert_equal i.topic, iz.topic, "Interest topics should be the same after changes to child" iz.topic = "Cow tipping" - assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to parent-owned instance" + assert_equal i.topic, iz.topic, "Interest topics should be the same after changes to parent-owned instance" end def test_trying_to_access_inverses_that_dont_exist_shouldnt_raise_an_error