Skip to content

Commit e220153

Browse files
committed
Revert to immediately retrieved collections by default
Closes #460 Introduce both the `config.active_resource.lazy_collections` configuration, as well as the `Base.lazy_collections` class attribute. Restore the original behavior of immediately retrieving collections by defaulting the initial value to `false`, but deprecate the behavior and encourage migrating to setting the value to `true`.
1 parent e577c6d commit e220153

File tree

6 files changed

+64
-7
lines changed

6 files changed

+64
-7
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,29 @@ people = Person.where(last_name: "Durden")
192192
people.first # => <Person::xxx 'first_name' => 'Tyler' ...>
193193
```
194194

195+
Collections are retrieved immediately by default. To defer the loading of the
196+
records until their first access, set `Base.lazy_collections = true`:
197+
198+
```ruby
199+
Person.lazy_collections = true
200+
201+
# Builds a lazy collection with an initial filter
202+
people = Person.where(first_name: "Tyler")
203+
204+
# Modifies the lazy collection with an additional filter
205+
people = people.where(last_name: "Durden")
206+
207+
# Expects a response of
208+
#
209+
# [
210+
# {"id":1,"first_name":"Tyler","last_name":"Durden"},
211+
# ]
212+
#
213+
# for GET http://api.people.com:3000/people.json?first_name=Tyler&last_name=Durden
214+
215+
people.first # => <Person::xxx 'first_name' => 'Tyler' ...>
216+
```
217+
195218
### Create
196219

197220
Creating a new resource submits the JSON form of the resource as the body of the request and expects

lib/active_resource/base.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,8 @@ def self.logger=(logger)
380380
class_attribute :connection_class
381381
self.connection_class = Connection
382382

383+
class_attribute :lazy_collections, instance_accessor: false, default: false
384+
383385
class << self
384386
include ThreadsafeAttributes
385387
threadsafe_attribute :_headers, :_connection, :_user, :_password, :_bearer_token, :_site, :_proxy
@@ -1126,7 +1128,11 @@ def last(*args)
11261128
# This is an alias for find(:all). You can pass in all the same
11271129
# arguments to this method as you can to <tt>find(:all)</tt>
11281130
def all(*args)
1129-
WhereClause.new(self, *args)
1131+
if lazy_collections
1132+
WhereClause.new(self, *args)
1133+
else
1134+
find(:all, *args)
1135+
end
11301136
end
11311137

11321138
# This is an alias for all. You can pass in all the same

lib/active_resource/railtie.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class Railtie < Rails::Railtie
88
config.eager_load_namespaces << ActiveResource
99

1010
config.active_resource = ActiveSupport::OrderedOptions.new
11+
config.active_resource.lazy_collections = false
1112

1213
initializer "active_resource.set_configs" do |app|
1314
ActiveSupport.on_load(:active_resource) do

test/cases/finder_test.rb

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,28 @@ def test_all
6161
assert_equal "David", all.last.name
6262
end
6363

64+
def test_all_immediately_finds_by_default
65+
requests = ActiveResource::HttpMock.requests
66+
67+
collection = Person.all
68+
69+
assert_equal [ "/people.json" ], requests.map(&:path)
70+
assert_kind_of Person, collection.first
71+
end
72+
73+
def test_all_with_lazy_collections
74+
requests = ActiveResource::HttpMock.requests
75+
76+
collection = DeferredPerson.all
77+
78+
assert_empty requests.map(&:path)
79+
80+
resource = collection.first
81+
82+
assert_equal [ "/people.json" ], requests.map(&:path)
83+
assert_kind_of Person, resource
84+
end
85+
6486
def test_all_with_params
6587
all = StreetAddress.all(params: { person_id: 1 })
6688
assert_equal 1, all.size
@@ -84,7 +106,7 @@ def test_where_with_clauses
84106
def test_where_with_multiple_where_clauses
85107
ActiveResource::HttpMock.respond_to.get "/people.json?id=2&name=david", {}, @people_david
86108

87-
people = Person.where(id: 2).where(name: "david")
109+
people = DeferredPerson.where(id: 2).where(name: "david")
88110
assert_equal 1, people.size
89111
assert_kind_of Person, people.first
90112
assert_equal 2, people.first.id
@@ -94,7 +116,7 @@ def test_where_with_multiple_where_clauses
94116
def test_where_chained_from_all
95117
ActiveResource::HttpMock.respond_to.get "/records.json?id=2", {}, @people_david
96118

97-
people = Person.all(from: "/records.json").where(id: 2)
119+
people = DeferredPerson.all(from: "/records.json").where(id: 2)
98120
assert_equal 1, people.size
99121
assert_kind_of Person, people.first
100122
assert_equal 2, people.first.id
@@ -104,7 +126,7 @@ def test_where_chained_from_all
104126
def test_where_with_chained_into_all
105127
ActiveResource::HttpMock.respond_to.get "/records.json?id=2&name=david", {}, @people_david
106128

107-
people = Person.where(id: 2).all(from: "/records.json", params: { name: "david" })
129+
people = DeferredPerson.where(id: 2).all(from: "/records.json", params: { name: "david" })
108130
assert_equal 1, people.size
109131
assert_kind_of Person, people.first
110132
assert_equal 2, people.first.id
@@ -113,7 +135,7 @@ def test_where_with_chained_into_all
113135

114136
def test_where_loading
115137
ActiveResource::HttpMock.respond_to.get "/people.json?id=2", {}, @people_david
116-
people = Person.where(id: 2)
138+
people = DeferredPerson.where(id: 2)
117139

118140
assert_changes -> { ActiveResource::HttpMock.requests.count }, from: 0, to: 1 do
119141
people.load
@@ -125,7 +147,7 @@ def test_where_loading
125147

126148
def test_where_reloading
127149
ActiveResource::HttpMock.respond_to.get "/people.json?id=2", {}, @people_david
128-
people = Person.where(id: 2)
150+
people = DeferredPerson.where(id: 2)
129151

130152
assert_changes -> { ActiveResource::HttpMock.requests.count }, from: 0, to: 1 do
131153
assert_equal 1, people.size

test/cases/notifications_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def setup
1515
end
1616

1717
def test_get_request_with_params
18-
payload = capture_notifications { Person.where(name: "Matz").load }
18+
payload = capture_notifications { Person.where(name: "Matz") }
1919

2020
assert_equal :get, payload[:method]
2121
assert_equal "http://37s.sunrise.i:3000/people.json?name=Matz", payload[:request_uri]

test/fixtures/person.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ class Person < ActiveResource::Base
44
self.site = "http://37s.sunrise.i:3000"
55
end
66

7+
class DeferredPerson < Person
8+
self.element_name = "person"
9+
self.lazy_collections = true
10+
end
11+
712
module External
813
class Person < ActiveResource::Base
914
self.site = "http://atq.caffeine.intoxication.it"

0 commit comments

Comments
 (0)