diff --git a/README.md b/README.md index 515f832edf..a23f1418bb 100644 --- a/README.md +++ b/README.md @@ -192,6 +192,16 @@ people = Person.where(last_name: "Durden") people.first # => 'Tyler' ...> ``` +##### A note on finding all resources + +Previously, Active Resource would eagerly load resources when `Person.all` was called. This behaviour is now +deprecated and Active Resource now lazy loads collections. The http request is deferred until the collection is +explicitly accessed. + +You can opt-in to the new behaviour by setting the `ActiveResource::Base.lazy_collections = false`. +Note that this setting is temporary to allow your application to progressivly transition to the new behaviour. +This setting will be removed in the next versions of Active Resource. + ### Create Creating a new resource submits the JSON form of the resource as the body of the request and expects diff --git a/lib/active_resource/base.rb b/lib/active_resource/base.rb index edf92e5c25..0eb46da1fb 100644 --- a/lib/active_resource/base.rb +++ b/lib/active_resource/base.rb @@ -371,6 +371,7 @@ def self.logger=(logger) @@logger = logger end + class_attribute :lazy_collections, default: true, instance_accessor: false class_attribute :_query_format class_attribute :_format class_attribute :_collection_parser @@ -384,6 +385,16 @@ class << self include ThreadsafeAttributes threadsafe_attribute :_headers, :_connection, :_user, :_password, :_bearer_token, :_site, :_proxy + def new_lazy_collections=(value) + ActiveResource.deprecator.warn(<<~MSG) + ActiveResource::Base#lazy_collections= is deprecated with no replacement. + MSG + + self.old_lazy_collections = value + end + alias_method :old_lazy_collections=, :lazy_collections= + alias_method :lazy_collections=, :new_lazy_collections= + # Creates a schema for this resource - setting the attributes that are # known prior to fetching an instance from the remote system. # @@ -1126,7 +1137,11 @@ def last(*args) # This is an alias for find(:all). You can pass in all the same # arguments to this method as you can to find(:all) def all(*args) - WhereClause.new(self, *args) + if lazy_collections + WhereClause.new(self, *args) + else + find(:all, *args) + end end # This is an alias for all. You can pass in all the same diff --git a/test/cases/finder_test.rb b/test/cases/finder_test.rb index d2cad8e30d..09ec85d005 100644 --- a/test/cases/finder_test.rb +++ b/test/cases/finder_test.rb @@ -61,6 +61,30 @@ def test_all assert_equal "David", all.last.name end + def test_all_loads_the_collection_lazily + all = Person.all + assert_empty(ActiveResource::HttpMock.requests) + + assert_equal(2, all.size) + assert_not_empty(ActiveResource::HttpMock.requests) + end + + def test_all_loads_the_collection_eagerly + previous_value = ActiveResource::Base.lazy_collections + + assert_deprecated(/ActiveResource::Base#lazy_collections= is deprecated/, ActiveResource.deprecator) do + ActiveResource::Base.lazy_collections = false + end + + all = Person.all + assert_not_empty(ActiveResource::HttpMock.requests) + assert_equal(2, all.size) + ensure + assert_deprecated(/ActiveResource::Base#lazy_collections= is deprecated/, ActiveResource.deprecator) do + ActiveResource::Base.lazy_collections = previous_value + end + end + def test_all_with_params all = StreetAddress.all(params: { person_id: 1 }) assert_equal 1, all.size