From 2d1345c867a4d9c2ac5ba9b43a50ab8ffad5a69d Mon Sep 17 00:00:00 2001 From: Sean Doyle Date: Fri, 24 Oct 2025 16:01:49 -0400 Subject: [PATCH] Singletons: Fix broken `reload` method Prior to this commit, singleton resources were unable to invoke `reload` to re-fetch themselves and load new data. To resolve that issue, this commit introduces a protected `Base#find_self` method that can be overridden by the `Singleton#find_self` version. --- lib/active_resource/base.rb | 6 +++++- lib/active_resource/singleton.rb | 4 ++++ test/cases/callbacks_test.rb | 15 +++++++++++++++ test/singleton_test.rb | 14 ++++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/active_resource/base.rb b/lib/active_resource/base.rb index af43ed04d9..cff88d0f4d 100644 --- a/lib/active_resource/base.rb +++ b/lib/active_resource/base.rb @@ -1553,7 +1553,7 @@ def encode(options = {}) # my_branch.name # => "Wilson Road" def reload run_callbacks :reload do - self.load(self.class.find(to_param, params: @prefix_options).attributes, false, true) + self.load(find_self.attributes, false, true) end end @@ -1809,6 +1809,10 @@ def find_or_create_resource_for(name) end end + def find_self + self.class.find(to_param, params: @prefix_options) + end + def const_valid?(*const_args) self.class.const_defined?(*const_args) true diff --git a/lib/active_resource/singleton.rb b/lib/active_resource/singleton.rb index bdc68d06f5..29196e3925 100644 --- a/lib/active_resource/singleton.rb +++ b/lib/active_resource/singleton.rb @@ -141,5 +141,9 @@ def create(path = singleton_path) def singleton_path(options = nil) self.class.singleton_path(options || prefix_options) end + + def find_self + self.class.find(@prefix_options) + end end end diff --git a/test/cases/callbacks_test.rb b/test/cases/callbacks_test.rb index 9d15d02065..5355796c22 100644 --- a/test/cases/callbacks_test.rb +++ b/test/cases/callbacks_test.rb @@ -164,6 +164,21 @@ def test_reload ], developer.history end + def test_reload_singleton + weather = Weather.find + weather.reload + assert_equal [ + [ :before_reload, :method ], + [ :before_reload, :proc ], + [ :before_reload, :object ], + [ :before_reload, :block ], + [ :after_reload, :method ], + [ :after_reload, :proc ], + [ :after_reload, :object ], + [ :after_reload, :block ] + ], weather.history + end + def test_update developer = Developer.find(1) developer.save diff --git a/test/singleton_test.rb b/test/singleton_test.rb index 51d0fea7e2..cb14339bbc 100644 --- a/test/singleton_test.rb +++ b/test/singleton_test.rb @@ -143,4 +143,18 @@ def test_update weather.status = "Rainy" weather.save end + + def test_reload + setup_weather + + # First Create the Weather + weather = Weather.create!(status: "Sunny", temperature: 67) + + # Then reload it + weather.reload + + request = ActiveResource::HttpMock.requests.last + assert_equal :get, request.method + assert_equal "/weather.json", request.path + end end