-
Notifications
You must be signed in to change notification settings - Fork 362
[ISSUE-408] Lazy Network Calls on Collections #409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
0a0b151
b2836d9
ea9a994
b570702
c4347c9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -776,6 +776,33 @@ def format_extension | |
include_format_in_path ? ".#{format.extension}" : "" | ||
end | ||
|
||
# Instantiates a new record with the given options. | ||
# | ||
# This method creates a new instance of the class with the provided record and sets its `prefix_options` attribute. | ||
# | ||
# ==== Options | ||
# | ||
# +record+ [Object] The record to be instantiated. | ||
# +prefix_options+ [Hash, nil] Optional hash containing prefix options for the resource. Defaults to an empty hash. | ||
# | ||
# ==== Returns | ||
# | ||
# [Object] The newly instantiated resource. | ||
# | ||
# ==== Examples | ||
# | ||
# MyResource.instantiate_record(record) | ||
# # Creates a new MyResource instance with default prefix options. | ||
# | ||
# MyResource.instantiate_record(record, { prefix: "admin" }) | ||
# # Creates a new MyResource instance with prefix set to "admin". | ||
# | ||
def instantiate_record(record, prefix_options = {}) | ||
new(record, true).tap do |resource| | ||
resource.prefix_options = prefix_options | ||
end | ||
end | ||
Comment on lines
+800
to
+804
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed from private to public |
||
|
||
# Gets the element path for the given ID in +id+. If the +query_options+ parameter is omitted, Rails | ||
# will split from the \prefix options. | ||
# | ||
|
@@ -1096,23 +1123,12 @@ def find_every(options) | |
params = options[:params] | ||
prefix_options, query_options = split_options(params) | ||
|
||
response = | ||
case from = options[:from] | ||
when Symbol | ||
get(from, params) | ||
when String | ||
path = "#{from}#{query_string(query_options)}" | ||
format.decode(connection.get(path, headers).body) | ||
else | ||
path = collection_path(prefix_options, query_options) | ||
format.decode(connection.get(path, headers).body) | ||
end | ||
|
||
instantiate_collection(response || [], query_options, prefix_options) | ||
rescue ActiveResource::ResourceNotFound | ||
# Swallowing ResourceNotFound exceptions and return nil - as per | ||
# ActiveRecord. | ||
nil | ||
collection_parser.new([], options[:from]).tap do |parser| | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Network call now gets made within the |
||
parser.resource_class = self | ||
parser.query_params = query_options | ||
parser.prefix_options = prefix_options | ||
parser.path_params = params | ||
end | ||
end | ||
|
||
# Find a single resource from a one-off URL | ||
|
@@ -1140,13 +1156,6 @@ def instantiate_collection(collection, original_params = {}, prefix_options = {} | |
end.collect! { |record| instantiate_record(record, prefix_options) } | ||
end | ||
|
||
def instantiate_record(record, prefix_options = {}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Made public |
||
new(record, true).tap do |resource| | ||
resource.prefix_options = prefix_options | ||
end | ||
end | ||
|
||
|
||
# Accepts a URI and creates the site URI from that. | ||
def create_site_uri_from(site) | ||
site.is_a?(URI) ? site.dup : URI.parse(site) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,14 +9,6 @@ def setup | |
end | ||
|
||
class BasicCollectionTest < CollectionTest | ||
def test_collection_respond_to_collect! | ||
assert @collection.respond_to?(:collect!) | ||
end | ||
|
||
def test_collection_respond_to_map! | ||
assert @collection.respond_to?(:map!) | ||
end | ||
Comment on lines
-12
to
-18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these methods were removed |
||
|
||
def test_collection_respond_to_first_or_create | ||
assert @collection.respond_to?(:first_or_create) | ||
end | ||
|
@@ -33,27 +25,14 @@ def test_first_or_initialize_without_resource_class_raises_error | |
assert_raise(RuntimeError) { @collection.first_or_initialize } | ||
end | ||
|
||
def test_collect_bang_modifies_elements | ||
elements = %w(a b c) | ||
@collection.elements = elements | ||
results = @collection.collect! { |i| i + "!" } | ||
assert_equal results.to_a, elements.collect! { |i| i + "!" } | ||
end | ||
|
||
def test_collect_bang_returns_collection | ||
@collection.elements = %w(a) | ||
results = @collection.collect! { |i| i + "!" } | ||
assert_kind_of ActiveResource::Collection, results | ||
end | ||
Comment on lines
-36
to
-47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these methods were removed |
||
|
||
def respond_to_where | ||
assert @collection.respond_to?(:where) | ||
end | ||
end | ||
|
||
class PaginatedCollection < ActiveResource::Collection | ||
attr_accessor :next_page | ||
def initialize(parsed = {}) | ||
def parse_response(parsed) | ||
@elements = parsed["results"] | ||
@next_page = parsed["next_page"] | ||
end | ||
|
@@ -73,6 +52,7 @@ class ReduxCollection < ActiveResource::Base | |
class CollectionInheritanceTest < ActiveSupport::TestCase | ||
def setup | ||
@post = { id: 1, title: "Awesome" } | ||
@post_even_more = { id: 1, title: "Awesome", subtitle: "EvenMore" } | ||
@posts_hash = { "results" => [@post], :next_page => "/paginated_posts.json?page=2" } | ||
@posts = @posts_hash.to_json | ||
@posts2 = { "results" => [@post.merge(id: 2)], :next_page => nil }.to_json | ||
|
@@ -85,6 +65,7 @@ def setup | |
mock.get "/paginated_posts.json?page=2", {}, @posts | ||
mock.get "/paginated_posts.json?title=test", {}, @empty_posts | ||
mock.get "/paginated_posts.json?page=2&title=Awesome", {}, @posts | ||
mock.get "/paginated_posts.json?subtitle=EvenMore&title=Awesome", {}, @posts | ||
mock.post "/paginated_posts.json", {}, nil | ||
end | ||
end | ||
|
@@ -97,12 +78,12 @@ def test_setting_collection_parser_resource_class | |
assert_equal PaginatedPost, PaginatedPost.where(page: 2).resource_class | ||
end | ||
|
||
def test_setting_collection_parser_original_params | ||
assert_equal({ page: 2 }, PaginatedPost.where(page: 2).original_params) | ||
def test_setting_collection_parser_query_params | ||
assert_equal({ page: 2 }, PaginatedPost.where(page: 2).query_params) | ||
end | ||
|
||
def test_custom_accessor | ||
assert_equal PaginatedPost.find(:all).next_page, @posts_hash[:next_page] | ||
assert_equal PaginatedPost.find(:all).call.next_page, @posts_hash[:next_page] | ||
end | ||
|
||
def test_first_or_create | ||
|
@@ -120,4 +101,17 @@ def test_where | |
next_posts = posts.where(title: "Awesome") | ||
assert_kind_of PaginatedCollection, next_posts | ||
end | ||
|
||
def test_where_lazy_chain | ||
expected_request = ActiveResource::Request.new( | ||
:get, | ||
"/paginated_posts.json?subtitle=EvenMore&title=Awesome", | ||
nil, | ||
{ "Accept" => "application/json" } | ||
) | ||
posts = PaginatedPost.where(title: "Awesome").where(subtitle: "EvenMore") | ||
assert_equal 0, ActiveResource::HttpMock.requests.count { |r| r == expected_request } | ||
posts.to_a | ||
assert_equal 1, ActiveResource::HttpMock.requests.count { |r| r == expected_request } | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because this is now lazy, no network call is actually made.