Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,29 @@ people = Person.where(last_name: "Durden")
people.first # => <Person::xxx 'first_name' => 'Tyler' ...>
```

Collections are retrieved immediately by default. To defer the loading of the
records until their first access, set `Base.lazy_collections = true`:

```ruby
Person.lazy_collections = true

# Builds a lazy collection with an initial filter
people = Person.where(first_name: "Tyler")

# Modifies the lazy collection with an additional filter
people = people.where(last_name: "Durden")

# Expects a response of
#
# [
# {"id":1,"first_name":"Tyler","last_name":"Durden"},
# ]
#
# for GET http://api.people.com:3000/people.json?first_name=Tyler&last_name=Durden

people.first # => <Person::xxx 'first_name' => 'Tyler' ...>
```

### Create

Creating a new resource submits the JSON form of the resource as the body of the request and expects
Expand Down
8 changes: 7 additions & 1 deletion lib/active_resource/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ def self.logger=(logger)
class_attribute :connection_class
self.connection_class = Connection

class_attribute :lazy_collections, instance_accessor: false, default: false

class << self
include ThreadsafeAttributes
threadsafe_attribute :_headers, :_connection, :_user, :_password, :_bearer_token, :_site, :_proxy
Expand Down Expand Up @@ -1126,7 +1128,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 <tt>find(:all)</tt>
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
Expand Down
1 change: 1 addition & 0 deletions lib/active_resource/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Railtie < Rails::Railtie
config.eager_load_namespaces << ActiveResource

config.active_resource = ActiveSupport::OrderedOptions.new
config.active_resource.lazy_collections = false

initializer "active_resource.set_configs" do |app|
ActiveSupport.on_load(:active_resource) do
Expand Down
32 changes: 27 additions & 5 deletions test/cases/finder_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,28 @@ def test_all
assert_equal "David", all.last.name
end

def test_all_immediately_finds_by_default
requests = ActiveResource::HttpMock.requests

collection = Person.all

assert_equal [ "/people.json" ], requests.map(&:path)
assert_kind_of Person, collection.first
end

def test_all_with_lazy_collections
requests = ActiveResource::HttpMock.requests

collection = DeferredPerson.all

assert_empty requests.map(&:path)

resource = collection.first

assert_equal [ "/people.json" ], requests.map(&:path)
assert_kind_of Person, resource
end

def test_all_with_params
all = StreetAddress.all(params: { person_id: 1 })
assert_equal 1, all.size
Expand All @@ -84,7 +106,7 @@ def test_where_with_clauses
def test_where_with_multiple_where_clauses
ActiveResource::HttpMock.respond_to.get "/people.json?id=2&name=david", {}, @people_david

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

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

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

def test_where_loading
ActiveResource::HttpMock.respond_to.get "/people.json?id=2", {}, @people_david
people = Person.where(id: 2)
people = DeferredPerson.where(id: 2)

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

def test_where_reloading
ActiveResource::HttpMock.respond_to.get "/people.json?id=2", {}, @people_david
people = Person.where(id: 2)
people = DeferredPerson.where(id: 2)

assert_changes -> { ActiveResource::HttpMock.requests.count }, from: 0, to: 1 do
assert_equal 1, people.size
Expand Down
2 changes: 1 addition & 1 deletion test/cases/notifications_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def setup
end

def test_get_request_with_params
payload = capture_notifications { Person.where(name: "Matz").load }
payload = capture_notifications { Person.where(name: "Matz") }

assert_equal :get, payload[:method]
assert_equal "http://37s.sunrise.i:3000/people.json?name=Matz", payload[:request_uri]
Expand Down
5 changes: 5 additions & 0 deletions test/fixtures/person.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ class Person < ActiveResource::Base
self.site = "http://37s.sunrise.i:3000"
end

class DeferredPerson < Person
self.element_name = "person"
self.lazy_collections = true
end

module External
class Person < ActiveResource::Base
self.site = "http://atq.caffeine.intoxication.it"
Expand Down