lhs 5.2.0 → 5.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/lhs/concerns/record/request.rb +39 -13
- data/lib/lhs/data.rb +1 -1
- data/lib/lhs/record.rb +1 -3
- data/lib/lhs/version.rb +1 -1
- data/spec/record/includes_spec.rb +53 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5e2d8c23fc37ece5d7b13aebd02f43df60aec96
|
4
|
+
data.tar.gz: 650560241439a1cb5b97c86894ef4a5e133d5bd4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d086164639d3fd4b3a40a772c2c98360cf212f6b58e6d55a5debe7317daecb341e42aec62948783e79f3eb18f398a607a9cffc99a7828d73f9fc02c894cc36a
|
7
|
+
data.tar.gz: 329fbdb7a8edc677a156588061af8e99e9a15db6bec9684f50e057157f6c4489fd1eb71d5c58c8378bb7e194682b2679e77b58c0ada1f3fc2b012bdfc70c2e9d
|
data/README.md
CHANGED
@@ -293,7 +293,7 @@ feedback.ratings # {:quality=>3}
|
|
293
293
|
|
294
294
|
## Include linked resources
|
295
295
|
|
296
|
-
When fetching records, you can specify in advance all the linked resources that you want to include in the results. With `includes`, LHS ensures that all matching and explicitly linked resources are loaded and merged.
|
296
|
+
When fetching records, you can specify in advance all the linked resources that you want to include in the results. With `includes`, LHS ensures that all matching and explicitly linked resources are loaded and merged, if they're included in the server response.
|
297
297
|
|
298
298
|
The implementation is heavily influenced by [http://guides.rubyonrails.org/active_record_class_querying](http://guides.rubyonrails.org/active_record_class_querying.html#eager-loading-associations) and you should read it to understand this feature in all its glory.
|
299
299
|
|
@@ -26,6 +26,7 @@ class LHS::Record
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def convert_option_to_endpoints(option)
|
29
|
+
return unless option.present?
|
29
30
|
new_options = option.dup
|
30
31
|
url = option[:url]
|
31
32
|
endpoint = LHS::Endpoint.for_url(url)
|
@@ -38,10 +39,12 @@ class LHS::Record
|
|
38
39
|
|
39
40
|
# Extends existing raw data with additionaly fetched data
|
40
41
|
def extend_raw_data(data, addition, key)
|
41
|
-
if
|
42
|
+
return if addition.empty?
|
43
|
+
if data.collection?
|
42
44
|
data.each_with_index do |item, i|
|
43
45
|
item = item[i] if item.is_a? LHS::Collection
|
44
|
-
item
|
46
|
+
link = item[key.to_sym]
|
47
|
+
link.merge_raw!(addition[i]) if link.present?
|
45
48
|
end
|
46
49
|
elsif data._proxy.is_a? LHS::Item
|
47
50
|
data._raw[key.to_sym].merge!(addition._raw)
|
@@ -59,19 +62,25 @@ class LHS::Record
|
|
59
62
|
end
|
60
63
|
|
61
64
|
def handle_include(included, data, sub_includes = nil)
|
62
|
-
return
|
65
|
+
return if data.blank? || skip_loading_includes?(data, included)
|
63
66
|
options =
|
64
|
-
if data.
|
65
|
-
options_for_multiple(data, included)
|
67
|
+
if data.collection?
|
66
68
|
options_for_multiple(data, included)
|
67
69
|
else
|
68
70
|
url_option_for(data, included)
|
69
|
-
url_option_for(data, included)
|
70
71
|
end
|
71
72
|
addition = load_include(options, data, sub_includes)
|
72
73
|
extend_raw_data(data, addition, included)
|
73
74
|
end
|
74
75
|
|
76
|
+
def skip_loading_includes?(data, included)
|
77
|
+
if data.collection?
|
78
|
+
data.to_a.none? { |item| item[included].present? }
|
79
|
+
else
|
80
|
+
!data._raw.key?(included)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
75
84
|
# Load additional resources that are requested with include
|
76
85
|
def load_include(options, data, sub_includes)
|
77
86
|
record = record_for_options(options) || self
|
@@ -92,14 +101,31 @@ class LHS::Record
|
|
92
101
|
end
|
93
102
|
|
94
103
|
def multiple_requests(options)
|
95
|
-
options = options.map
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
104
|
+
options = options.map do |option|
|
105
|
+
next unless option.present?
|
106
|
+
process_options(option, find_endpoint(option[:params]))
|
107
|
+
end
|
108
|
+
data = LHC.request(options.compact).map { |response| LHS::Data.new(response.body, nil, self, response.request) }
|
109
|
+
data = restore_with_nils(data, locate_nils(options)) # nil objects in data provide location information for mapping
|
110
|
+
unless data.empty?
|
111
|
+
data = LHS::Data.new(data, nil, self)
|
112
|
+
handle_includes(including, data) if including
|
113
|
+
end
|
100
114
|
data
|
101
115
|
end
|
102
116
|
|
117
|
+
def locate_nils(array)
|
118
|
+
nils = []
|
119
|
+
array.each_with_index { |value, index| nils << index if value.nil? }
|
120
|
+
nils
|
121
|
+
end
|
122
|
+
|
123
|
+
def restore_with_nils(array, nils)
|
124
|
+
array = array.dup
|
125
|
+
nils.sort.each { |index| array.insert(index, nil) }
|
126
|
+
array
|
127
|
+
end
|
128
|
+
|
103
129
|
def options_for_multiple(data, key)
|
104
130
|
data.map do |item|
|
105
131
|
url_option_for(item, key)
|
@@ -119,7 +145,7 @@ class LHS::Record
|
|
119
145
|
def record_for_options(options)
|
120
146
|
records = []
|
121
147
|
if options.is_a?(Array)
|
122
|
-
options.each do |option|
|
148
|
+
options.compact.each do |option|
|
123
149
|
record = LHS::Record.for_url(option[:url])
|
124
150
|
next unless record
|
125
151
|
records.push(record)
|
@@ -143,7 +169,7 @@ class LHS::Record
|
|
143
169
|
|
144
170
|
def url_option_for(item, key)
|
145
171
|
link = item[key]
|
146
|
-
{ url: link.href }
|
172
|
+
return { url: link.href } if link.present? && link.href.present?
|
147
173
|
end
|
148
174
|
end
|
149
175
|
end
|
data/lib/lhs/data.rb
CHANGED
data/lib/lhs/record.rb
CHANGED
@@ -18,9 +18,7 @@ class LHS::Record
|
|
18
18
|
include Request
|
19
19
|
include Scope
|
20
20
|
|
21
|
-
delegate :_proxy, to: :_data
|
22
|
-
delegate :_endpoint, to: :_data
|
23
|
-
delegate :select, to: :_data
|
21
|
+
delegate :_proxy, :_endpoint, :merge_raw!, :select, to: :_data
|
24
22
|
|
25
23
|
def initialize(data = nil)
|
26
24
|
data = LHS::Data.new({}, nil, self.class) unless data
|
data/lib/lhs/version.rb
CHANGED
@@ -170,6 +170,59 @@ describe LHS::Record do
|
|
170
170
|
# rubocop:enable RSpec/InstanceVariable
|
171
171
|
end
|
172
172
|
end
|
173
|
+
|
174
|
+
context 'includes not present in response' do
|
175
|
+
before :each do
|
176
|
+
class Parent < LHS::Record
|
177
|
+
endpoint ':datastore/local-parents'
|
178
|
+
endpoint ':datastore/local-parents/:id'
|
179
|
+
end
|
180
|
+
|
181
|
+
class OptionalChild < LHS::Record
|
182
|
+
endpoint ':datastore/local-children/:id'
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'handles missing but included fields in single object response' do
|
187
|
+
stub_request(:get, "#{datastore}/local-parents/1")
|
188
|
+
.to_return(status: 200, body: {
|
189
|
+
'href' => "#{datastore}/local-parents/1",
|
190
|
+
'name' => 'RspecName'
|
191
|
+
}.to_json)
|
192
|
+
|
193
|
+
parent = Parent.includes(:optional_children).find(1)
|
194
|
+
expect(parent).not_to be nil
|
195
|
+
expect(parent.name).to eq 'RspecName'
|
196
|
+
expect(parent.optional_children).to be nil
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'handles missing but included fields in collection response' do
|
200
|
+
stub_request(:get, "#{datastore}/local-parents")
|
201
|
+
.to_return(status: 200, body: {
|
202
|
+
items: [
|
203
|
+
{
|
204
|
+
'href' => "#{datastore}/local-parents/1",
|
205
|
+
'name' => 'RspecParent'
|
206
|
+
}, {
|
207
|
+
'href' => "#{datastore}/local-parents/2",
|
208
|
+
'name' => 'RspecParent2',
|
209
|
+
'optional_child' => {
|
210
|
+
'href' => "#{datastore}/local-children/1"
|
211
|
+
}
|
212
|
+
}]
|
213
|
+
}.to_json)
|
214
|
+
|
215
|
+
stub_request(:get, "#{datastore}/local-children/1")
|
216
|
+
.to_return(status: 200, body: {
|
217
|
+
href: "#{datastore}/local_children/1",
|
218
|
+
name: 'RspecOptionalChild1'
|
219
|
+
}.to_json)
|
220
|
+
|
221
|
+
child = Parent.includes(:optional_child).where[1].optional_child
|
222
|
+
expect(child).not_to be nil
|
223
|
+
expect(child.name).to eq 'RspecOptionalChild1'
|
224
|
+
end
|
225
|
+
end
|
173
226
|
end
|
174
227
|
|
175
228
|
context 'links pointing to nowhere' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lhs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- https://github.com/local-ch/lhs/graphs/contributors
|
@@ -343,7 +343,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
343
343
|
requirements:
|
344
344
|
- Ruby >= 1.9.2
|
345
345
|
rubyforge_project:
|
346
|
-
rubygems_version: 2.
|
346
|
+
rubygems_version: 2.5.1
|
347
347
|
signing_key:
|
348
348
|
specification_version: 4
|
349
349
|
summary: Rails gem providing an easy, active-record-like interface for http json services
|