lhs 22.1.0 → 24.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +19 -5
- data/lhs.gemspec +2 -2
- data/lib/lhs/concerns/record/chainable.rb +4 -4
- data/lib/lhs/concerns/record/request.rb +19 -25
- data/lib/lhs/version.rb +1 -1
- data/spec/dummy/app/controllers/error_handling_with_chains_controller.rb +2 -2
- data/spec/record/error_handling_spec.rb +4 -4
- data/spec/record/find_in_parallel_spec.rb +1 -1
- data/spec/record/handle_includes_errors_spec.rb +1 -1
- data/spec/record/includes_first_page_spec.rb +14 -4
- metadata +7 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e31a9b37f1bc0f12b3a6c87933b145781ed3054e08ea4ea347d5b27d00a069ea
|
|
4
|
+
data.tar.gz: d67f414e70fdcae5567dcf5c81c2e2dec93237026e829c9dc9522df5eb778480
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f39832a96aa989660bfbaf051c53bd53c647d4e75f7b9fa3ca81ab1243ec94bd17828da931207f80fd57a9f98f38188cca659143912a01a4ffc5e197090f6b3a
|
|
7
|
+
data.tar.gz: 19ea228303da96f4f4e831825c19c98ea9a81c15b76ad645b3ecbe23532f0a7336eb87d815f432f2d25ee5d6f0c07d98963ed0ba5388022cd79521cd0ae04424
|
data/README.md
CHANGED
|
@@ -99,6 +99,8 @@ record.review # "Lunch was great
|
|
|
99
99
|
* [Change/Update existing records](#changeupdate-existing-records)
|
|
100
100
|
* [save](#save)
|
|
101
101
|
* [update](#update)
|
|
102
|
+
* [Directly via Record](#directly-via-record)
|
|
103
|
+
* [per Instance](#per-instance)
|
|
102
104
|
* [partial_update](#partial_update)
|
|
103
105
|
* [Endpoint url parameter injection during record creation/change](#endpoint-url-parameter-injection-during-record-creationchange)
|
|
104
106
|
* [Record validation](#record-validation)
|
|
@@ -119,8 +121,8 @@ record.review # "Lunch was great
|
|
|
119
121
|
* [Record getters](#record-getters)
|
|
120
122
|
* [Include linked resources (hyperlinks and hypermedia)](#include-linked-resources-hyperlinks-and-hypermedia)
|
|
121
123
|
* [Generate links from parameters](#generate-links-from-parameters)
|
|
122
|
-
* [Ensure the whole linked collection is included
|
|
123
|
-
* [Include the first linked page
|
|
124
|
+
* [Ensure the whole linked collection is included with includes](#ensure-the-whole-linked-collection-is-included-with-includes)
|
|
125
|
+
* [Include only the first linked page of a linked collection: includes_first_page](#include-only-the-first-linked-page-of-a-linked-collection-includes_first_page)
|
|
124
126
|
* [Include various levels of linked data](#include-various-levels-of-linked-data)
|
|
125
127
|
* [Identify and cast known records when including records](#identify-and-cast-known-records-when-including-records)
|
|
126
128
|
* [Apply options for requests performed to fetch included records](#apply-options-for-requests-performed-to-fetch-included-records)
|
|
@@ -152,6 +154,7 @@ record.review # "Lunch was great
|
|
|
152
154
|
|
|
153
155
|
|
|
154
156
|
|
|
157
|
+
|
|
155
158
|
## Installation/Startup checklist
|
|
156
159
|
|
|
157
160
|
- [ ] Install LHS gem, preferably via `Gemfile`
|
|
@@ -976,7 +979,7 @@ If you need to render some different view in Rails based on an LHS error raised
|
|
|
976
979
|
|
|
977
980
|
def show
|
|
978
981
|
@records = Record
|
|
979
|
-
.
|
|
982
|
+
.rescue(LHC::Error, ->(error){ rescue_from(error) })
|
|
980
983
|
.where(color: 'blue')
|
|
981
984
|
render 'show'
|
|
982
985
|
render_error if @error
|
|
@@ -984,7 +987,7 @@ end
|
|
|
984
987
|
|
|
985
988
|
private
|
|
986
989
|
|
|
987
|
-
def
|
|
990
|
+
def rescue_from(error)
|
|
988
991
|
@error = error
|
|
989
992
|
nil
|
|
990
993
|
end
|
|
@@ -1009,7 +1012,7 @@ If you want to inject values for the failing records, that might not have been f
|
|
|
1009
1012
|
# app/controllers/some_controller.rb
|
|
1010
1013
|
|
|
1011
1014
|
data = Record
|
|
1012
|
-
.
|
|
1015
|
+
.rescue(LHC::Unauthorized, ->(response) { Record.new(name: 'unknown') })
|
|
1013
1016
|
.find(1, 2, 3)
|
|
1014
1017
|
|
|
1015
1018
|
data[1].name # 'unknown'
|
|
@@ -2276,6 +2279,17 @@ In parallel:
|
|
|
2276
2279
|
GET https://service.example.com/places/4 { headers: { 'Authentication': 'Bearer 123' } }
|
|
2277
2280
|
```
|
|
2278
2281
|
|
|
2282
|
+
Here is another example, if you want to ignore errors, that occure while you fetch included resources:
|
|
2283
|
+
|
|
2284
|
+
```ruby
|
|
2285
|
+
# app/controllers/some_controller.rb
|
|
2286
|
+
|
|
2287
|
+
feedback = Feedback
|
|
2288
|
+
.includes(campaign: :entry)
|
|
2289
|
+
.references(campaign: { ignore: LHC::NotFound })
|
|
2290
|
+
.find(12345)
|
|
2291
|
+
```
|
|
2292
|
+
|
|
2279
2293
|
### Record batch processing
|
|
2280
2294
|
|
|
2281
2295
|
**Be careful using methods for batch processing. They could result in a lot of HTTP requests!**
|
data/lhs.gemspec
CHANGED
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
|
|
|
24
24
|
|
|
25
25
|
s.add_dependency 'activemodel'
|
|
26
26
|
s.add_dependency 'activesupport', '>= 4.2.11'
|
|
27
|
-
s.add_dependency 'lhc', '>=
|
|
27
|
+
s.add_dependency 'lhc', '>= 12.1.1', '< 13'
|
|
28
28
|
s.add_dependency 'local_uri'
|
|
29
29
|
|
|
30
30
|
s.add_development_dependency 'capybara'
|
|
@@ -39,5 +39,5 @@ Gem::Specification.new do |s|
|
|
|
39
39
|
s.add_development_dependency 'sprockets', '< 4'
|
|
40
40
|
s.add_development_dependency 'webmock'
|
|
41
41
|
|
|
42
|
-
s.license = 'GPL-3'
|
|
42
|
+
s.license = 'GPL-3.0'
|
|
43
43
|
end
|
|
@@ -52,7 +52,7 @@ class LHS::Record
|
|
|
52
52
|
Chain.new(self, Pagination.new(per: argument))
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
def
|
|
55
|
+
def rescue(error_class, handler)
|
|
56
56
|
Chain.new(self, ErrorHandling.new(error_class => handler))
|
|
57
57
|
end
|
|
58
58
|
|
|
@@ -255,7 +255,7 @@ class LHS::Record
|
|
|
255
255
|
push(Pagination.new(per: argument))
|
|
256
256
|
end
|
|
257
257
|
|
|
258
|
-
def
|
|
258
|
+
def rescue(error_class, handler)
|
|
259
259
|
push(ErrorHandling.new(error_class => handler))
|
|
260
260
|
end
|
|
261
261
|
|
|
@@ -348,8 +348,8 @@ class LHS::Record
|
|
|
348
348
|
def resolved_options
|
|
349
349
|
options = chain_options
|
|
350
350
|
options = options.deep_merge(params: chain_parameters.merge(chain_pagination))
|
|
351
|
-
options = options.merge(
|
|
352
|
-
options = options.merge(
|
|
351
|
+
options = options.merge(rescue: chain_error_handler) if chain_error_handler.present?
|
|
352
|
+
options = options.merge(ignore: chain_ignored_errors) if chain_ignored_errors.present?
|
|
353
353
|
options = options.merge(including: chain_includes) if chain_includes.present?
|
|
354
354
|
options = options.merge(referencing: chain_references) if chain_references.present?
|
|
355
355
|
options
|
|
@@ -138,6 +138,7 @@ class LHS::Record
|
|
|
138
138
|
end
|
|
139
139
|
|
|
140
140
|
def extend_base_item!(data, addition, key)
|
|
141
|
+
return if addition.nil?
|
|
141
142
|
if addition.collection?
|
|
142
143
|
extend_base_item_with_collection!(data, addition, key)
|
|
143
144
|
else # simple case merges hash into hash
|
|
@@ -187,7 +188,7 @@ class LHS::Record
|
|
|
187
188
|
options = extend_with_reference(options, reference)
|
|
188
189
|
addition = load_include(options, data, sub_includes, reference)
|
|
189
190
|
extend_raw_data!(data, addition, included)
|
|
190
|
-
expand_addition!(data, included, options)
|
|
191
|
+
expand_addition!(data, included, options) unless expanded_data?(addition)
|
|
191
192
|
end
|
|
192
193
|
end
|
|
193
194
|
|
|
@@ -205,28 +206,24 @@ class LHS::Record
|
|
|
205
206
|
def expand_addition!(data, included, reference)
|
|
206
207
|
addition = data[included]
|
|
207
208
|
options = options_for_data(addition)
|
|
208
|
-
options = extend_with_reference(options, reference
|
|
209
|
+
options = extend_with_reference(options, reference)
|
|
209
210
|
record = record_for_options(options) || self
|
|
210
211
|
options = convert_options_to_endpoints(options) if record_for_options(options)
|
|
211
|
-
expanded_data =
|
|
212
|
-
record.request(options)
|
|
213
|
-
rescue LHC::NotFound
|
|
214
|
-
LHS::Data.new({}, data, record)
|
|
215
|
-
end
|
|
212
|
+
expanded_data = record.request(options)
|
|
216
213
|
extend_raw_data!(data, expanded_data, included)
|
|
217
214
|
end
|
|
218
215
|
|
|
219
|
-
def
|
|
216
|
+
def expanded_data?(addition)
|
|
220
217
|
return false if addition.blank?
|
|
221
218
|
if addition.item?
|
|
222
|
-
(addition._raw.keys - [:href]).
|
|
219
|
+
(addition._raw.keys - [:href]).any?
|
|
223
220
|
elsif addition.collection?
|
|
224
|
-
addition.
|
|
221
|
+
addition.any? do |item|
|
|
225
222
|
next if item.blank?
|
|
226
223
|
if item._raw.is_a?(Hash)
|
|
227
|
-
(item._raw.keys - [:href]).
|
|
224
|
+
(item._raw.keys - [:href]).any?
|
|
228
225
|
elsif item._raw.is_a?(Array)
|
|
229
|
-
item.any? { |item| (item._raw.keys - [:href]).
|
|
226
|
+
item.any? { |item| (item._raw.keys - [:href]).any? }
|
|
230
227
|
end
|
|
231
228
|
end
|
|
232
229
|
end
|
|
@@ -234,7 +231,8 @@ class LHS::Record
|
|
|
234
231
|
|
|
235
232
|
# Extends request options with options provided for this reference
|
|
236
233
|
def extend_with_reference(options, reference)
|
|
237
|
-
return options
|
|
234
|
+
return options if reference.blank?
|
|
235
|
+
reference = reference.except(:url)
|
|
238
236
|
options ||= {}
|
|
239
237
|
if options.is_a?(Array)
|
|
240
238
|
options.map { |request_options| request_options.merge(reference) if request_options.present? }
|
|
@@ -348,18 +346,14 @@ class LHS::Record
|
|
|
348
346
|
end
|
|
349
347
|
|
|
350
348
|
# Load additional resources that are requested with include
|
|
351
|
-
def load_include(options,
|
|
349
|
+
def load_include(options, _data, sub_includes, references)
|
|
352
350
|
record = record_for_options(options) || self
|
|
353
351
|
options = convert_options_to_endpoints(options) if record_for_options(options)
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
load_include_simple!(options, record)
|
|
360
|
-
end
|
|
361
|
-
rescue LHC::NotFound
|
|
362
|
-
LHS::Data.new({}, data, record)
|
|
352
|
+
prepare_options_for_include_request!(options, sub_includes, references)
|
|
353
|
+
if references && references[:all] # include all linked resources
|
|
354
|
+
load_include_all!(options, record, sub_includes, references)
|
|
355
|
+
else # simply request first page/batch
|
|
356
|
+
load_include_simple!(options, record)
|
|
363
357
|
end
|
|
364
358
|
end
|
|
365
359
|
|
|
@@ -372,7 +366,7 @@ class LHS::Record
|
|
|
372
366
|
|
|
373
367
|
def load_include_simple!(options, record)
|
|
374
368
|
data = record.request(options)
|
|
375
|
-
warn "[WARNING] You included `#{options[:url]}`, but this endpoint is paginated. You might want to use `includes_all` instead of `includes` (https://github.com/local-ch/lhs#includes_all-for-paginated-endpoints)." if paginated?(data._raw)
|
|
369
|
+
warn "[WARNING] You included `#{options[:url]}`, but this endpoint is paginated. You might want to use `includes_all` instead of `includes` (https://github.com/local-ch/lhs#includes_all-for-paginated-endpoints)." if data && paginated?(data._raw)
|
|
376
370
|
data
|
|
377
371
|
end
|
|
378
372
|
|
|
@@ -510,7 +504,7 @@ class LHS::Record
|
|
|
510
504
|
options = options.deep_dup
|
|
511
505
|
options[:ignored_errors] = ignored_errors if ignored_errors.present?
|
|
512
506
|
options[:params]&.deep_symbolize_keys!
|
|
513
|
-
options[:
|
|
507
|
+
options[:rescue] = merge_error_handlers(options[:rescue]) if options[:rescue]
|
|
514
508
|
options = (provider_options || {})
|
|
515
509
|
.deep_merge(endpoint.options || {})
|
|
516
510
|
.deep_merge(options)
|
data/lib/lhs/version.rb
CHANGED
|
@@ -6,7 +6,7 @@ class ErrorHandlingWithChainsController < ApplicationController
|
|
|
6
6
|
# in the view (during render 'show')
|
|
7
7
|
def fetch_in_view
|
|
8
8
|
@records = DummyRecord
|
|
9
|
-
.
|
|
9
|
+
.rescue(LHC::Error, ->(error) { handle_error(error) })
|
|
10
10
|
.where(color: 'blue')
|
|
11
11
|
render 'show'
|
|
12
12
|
render_error if @error
|
|
@@ -16,7 +16,7 @@ class ErrorHandlingWithChainsController < ApplicationController
|
|
|
16
16
|
# before the view is rendered
|
|
17
17
|
def fetch_in_controller
|
|
18
18
|
@records = DummyRecord
|
|
19
|
-
.
|
|
19
|
+
.rescue(LHC::Error, ->(error) { handle_error(error) })
|
|
20
20
|
.where(color: 'blue').fetch
|
|
21
21
|
render 'show'
|
|
22
22
|
render_error if @error
|
|
@@ -15,14 +15,14 @@ describe LHS::Record do
|
|
|
15
15
|
|
|
16
16
|
it 'allows to chain error handling' do
|
|
17
17
|
expect {
|
|
18
|
-
Record.where(color: 'blue').
|
|
18
|
+
Record.where(color: 'blue').rescue(LHC::Error, ->(_error) { handler.handle }).first
|
|
19
19
|
}.not_to raise_error
|
|
20
20
|
expect(handler).to have_received(:handle)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
it 'reraises in case chained error is not matched' do
|
|
24
24
|
expect {
|
|
25
|
-
Record.where(color: 'blue').
|
|
25
|
+
Record.where(color: 'blue').rescue(LHC::Conflict, ->(_error) { handler.handle }).first
|
|
26
26
|
}.to raise_error(LHC::Error)
|
|
27
27
|
expect(handler).not_to have_received(:handle)
|
|
28
28
|
end
|
|
@@ -30,8 +30,8 @@ describe LHS::Record do
|
|
|
30
30
|
it 'calls all the handlers' do
|
|
31
31
|
expect {
|
|
32
32
|
Record.where(color: 'blue')
|
|
33
|
-
.
|
|
34
|
-
.
|
|
33
|
+
.rescue(LHC::Error, ->(_error) { handler.handle_1 })
|
|
34
|
+
.rescue(LHC::Error, ->(_error) { handler.handle_2 })
|
|
35
35
|
.first
|
|
36
36
|
}.not_to raise_error
|
|
37
37
|
expect(handler).to have_received(:handle_1)
|
|
@@ -33,7 +33,7 @@ describe LHS::Record do
|
|
|
33
33
|
it 'applies error handlers from the chain and returns whatever the error handler returns' do
|
|
34
34
|
stub_request(:get, "http://datastore/records/2").to_return(status: 401)
|
|
35
35
|
data = Record
|
|
36
|
-
.
|
|
36
|
+
.rescue(LHC::Unauthorized, ->(_response) { Record.new(name: 'unknown') })
|
|
37
37
|
.find(1, 2, 3)
|
|
38
38
|
expect(data[1].name).to eq 'unknown'
|
|
39
39
|
end
|
|
@@ -25,7 +25,7 @@ describe LHS::Record do
|
|
|
25
25
|
|
|
26
26
|
it 'allows to pass error_handling for includes to LHC' do
|
|
27
27
|
handler = ->(_) { return { deleted: true } }
|
|
28
|
-
record = Record.includes_first_page(:other).references(other: {
|
|
28
|
+
record = Record.includes_first_page(:other).references(other: { rescue: { LHC::NotFound => handler } }).find(id: 1)
|
|
29
29
|
|
|
30
30
|
expect(record.other.deleted).to be(true)
|
|
31
31
|
end
|
|
@@ -224,7 +224,7 @@ describe LHS::Record do
|
|
|
224
224
|
end
|
|
225
225
|
|
|
226
226
|
context 'links pointing to nowhere' do
|
|
227
|
-
|
|
227
|
+
before do
|
|
228
228
|
class Feedback < LHS::Record
|
|
229
229
|
endpoint '{+datastore}/feedbacks'
|
|
230
230
|
endpoint '{+datastore}/feedbacks/{id}'
|
|
@@ -238,10 +238,20 @@ describe LHS::Record do
|
|
|
238
238
|
|
|
239
239
|
stub_request(:get, "#{datastore}/content-ads/51dfc5690cf271c375c5a12d")
|
|
240
240
|
.to_return(status: 404)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
it 'raises LHC::NotFound for links that cannot be included' do
|
|
244
|
+
expect(-> {
|
|
245
|
+
Feedback.includes_first_page(campaign: :entry).find(123)
|
|
246
|
+
}).to raise_error LHC::NotFound
|
|
247
|
+
end
|
|
241
248
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
249
|
+
it 'ignores LHC::NotFound for links that cannot be included if configured so with reference options' do
|
|
250
|
+
feedback = Feedback
|
|
251
|
+
.includes_first_page(campaign: :entry)
|
|
252
|
+
.references(campaign: { ignore: [LHC::NotFound] })
|
|
253
|
+
.find(123)
|
|
254
|
+
expect(feedback.campaign._raw.keys.length).to eq 1
|
|
245
255
|
end
|
|
246
256
|
end
|
|
247
257
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lhs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 24.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- https://github.com/local-ch/lhs/graphs/contributors
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-07-
|
|
11
|
+
date: 2020-07-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activemodel
|
|
@@ -44,20 +44,20 @@ dependencies:
|
|
|
44
44
|
requirements:
|
|
45
45
|
- - ">="
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
47
|
+
version: 12.1.1
|
|
48
48
|
- - "<"
|
|
49
49
|
- !ruby/object:Gem::Version
|
|
50
|
-
version: '
|
|
50
|
+
version: '13'
|
|
51
51
|
type: :runtime
|
|
52
52
|
prerelease: false
|
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
|
54
54
|
requirements:
|
|
55
55
|
- - ">="
|
|
56
56
|
- !ruby/object:Gem::Version
|
|
57
|
-
version:
|
|
57
|
+
version: 12.1.1
|
|
58
58
|
- - "<"
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: '
|
|
60
|
+
version: '13'
|
|
61
61
|
- !ruby/object:Gem::Dependency
|
|
62
62
|
name: local_uri
|
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -548,7 +548,7 @@ files:
|
|
|
548
548
|
- spec/views/form_for_spec.rb
|
|
549
549
|
homepage: https://github.com/local-ch/lhs
|
|
550
550
|
licenses:
|
|
551
|
-
- GPL-3
|
|
551
|
+
- GPL-3.0
|
|
552
552
|
metadata: {}
|
|
553
553
|
post_install_message:
|
|
554
554
|
rdoc_options: []
|