From c45c9cfb011fce54c319555c8852d915ff2ef97a Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Wed, 17 May 2017 00:40:26 +0900 Subject: [PATCH] Cache the association proxy object Some third party modules expects that association returns same proxy object each time (e.g. for stubbing collection methods: https://github.com/rspec/rspec-rails/issues/1817). So I decided that cache the proxy object and reset scope in the proxy object each time. Related context: https://github.com/rails/rails/commit/c86a32d7451c5d901620ac58630460915292f88b#commitcomment-2784312 --- .../active_record/associations/collection_association.rb | 3 ++- .../lib/active_record/associations/collection_proxy.rb | 9 ++++++--- activerecord/test/cases/associations_test.rb | 5 +++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb index 62c944fce3..edc53e2517 100644 --- a/activerecord/lib/active_record/associations/collection_association.rb +++ b/activerecord/lib/active_record/associations/collection_association.rb @@ -30,7 +30,8 @@ def reader reload end - CollectionProxy.create(klass, self) + @proxy ||= CollectionProxy.create(klass, self) + @proxy.reset_scope end # Implements the writer method, e.g. foo.items= for Foo.has_many :items diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb index 89cfa07be3..8cdb508c43 100644 --- a/activerecord/lib/active_record/associations/collection_proxy.rb +++ b/activerecord/lib/active_record/associations/collection_proxy.rb @@ -1087,9 +1087,8 @@ def clear # person.pets(true) # fetches pets from the database # # => [#] def reload - @scope = nil proxy_association.reload - self + reset_scope end # Unloads the association. Returns +self+. @@ -1109,9 +1108,13 @@ def reload # person.pets # fetches pets from the database # # => [#] def reset - @scope = nil proxy_association.reset proxy_association.reset_scope + reset_scope + end + + def reset_scope # :nodoc: + @scope = nil self end diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb index 4ab690bfc6..ff31c82794 100644 --- a/activerecord/test/cases/associations_test.rb +++ b/activerecord/test/cases/associations_test.rb @@ -220,6 +220,11 @@ def test_scoped_allows_conditions assert_equal david.projects, david.projects.scope end + test "proxy object is cached" do + david = developers(:david) + assert_same david.projects, david.projects + end + test "inverses get set of subsets of the association" do man = Man.create man.interests.create -- GitLab