lhs 24.0.0 → 24.1.2
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 +59 -1
- data/docs/accessing-data-in-lhs.png +0 -0
- data/lib/lhs/concerns/collection/internal_collection.rb +28 -4
- data/lib/lhs/concerns/data/extend.rb +83 -0
- data/lib/lhs/concerns/record/request.rb +3 -71
- data/lib/lhs/data.rb +15 -0
- data/lib/lhs/version.rb +1 -1
- data/spec/record/compact_spec.rb +90 -0
- data/spec/record/includes_expanded_spec.rb +37 -0
- data/spec/record/references_spec.rb +43 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9bf423437a22db27b055a47b11b77edad75d4fb22895330bb33b439c03d9e89f
|
4
|
+
data.tar.gz: 228b803160ce5cfeaa801e25eac36a84fa75196ca906183336e649cd17c5604a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd83a4d879c72a201b29420021562da78945a1ef731a87023c735efe90144f1d088318c293064d9361aa559df8405132d88af0011225c43e675144d1c5af7b5f
|
7
|
+
data.tar.gz: 6da5e46c3e113bbf48a3821a02b88a6379bd54846889acb7cf77ce269be9645404d443656215979d7b3311ae1139ba07c00993542cacbd17562dc79b733af8eb
|
data/README.md
CHANGED
@@ -126,6 +126,7 @@ record.review # "Lunch was great
|
|
126
126
|
* [Include various levels of linked data](#include-various-levels-of-linked-data)
|
127
127
|
* [Identify and cast known records when including records](#identify-and-cast-known-records-when-including-records)
|
128
128
|
* [Apply options for requests performed to fetch included records](#apply-options-for-requests-performed-to-fetch-included-records)
|
129
|
+
* [compact: Remove included resources that didn't return any records](#compact-remove-included-resources-that-didnt-return-any-records)
|
129
130
|
* [Record batch processing](#record-batch-processing)
|
130
131
|
* [all](#all-1)
|
131
132
|
* [Using all, when endpoint does not implement response pagination meta data](#using-all-when-endpoint-does-not-implement-response-pagination-meta-data)
|
@@ -149,12 +150,15 @@ record.review # "Lunch was great
|
|
149
150
|
* [Test query chains](#test-query-chains)
|
150
151
|
* [By explicitly resolving the chain: fetch](#by-explicitly-resolving-the-chain-fetch)
|
151
152
|
* [Without resolving the chain: where_values_hash](#without-resolving-the-chain-where_values_hash)
|
153
|
+
* [Extended developer documentation](#extended-developer-documentation)
|
154
|
+
* [Accessing data in LHS](#accessing-data-in-lhs)
|
152
155
|
* [License](#license)
|
153
156
|
|
154
157
|
|
155
158
|
|
156
159
|
|
157
160
|
|
161
|
+
|
158
162
|
## Installation/Startup checklist
|
159
163
|
|
160
164
|
- [ ] Install LHS gem, preferably via `Gemfile`
|
@@ -1698,7 +1702,7 @@ record.partial_update(recommended: true)
|
|
1698
1702
|
|
1699
1703
|
```
|
1700
1704
|
```
|
1701
|
-
POST https://service.example.com/records/1z-5r1fkaj { body: "{ '
|
1705
|
+
POST https://service.example.com/records/1z-5r1fkaj { body: "{ 'recommended': true }" }
|
1702
1706
|
```
|
1703
1707
|
|
1704
1708
|
-> See [record validation](#record-validation) for how to handle validation errors when updating records.
|
@@ -2290,6 +2294,54 @@ feedback = Feedback
|
|
2290
2294
|
.find(12345)
|
2291
2295
|
```
|
2292
2296
|
|
2297
|
+
#### compact: Remove included resources that didn't return any records
|
2298
|
+
|
2299
|
+
In case you include nested data and ignored errors while including, it can happen that you get back a collection that contains data based on response errors:
|
2300
|
+
|
2301
|
+
```ruby
|
2302
|
+
# app/controllers/some_controller.rb
|
2303
|
+
|
2304
|
+
user = User
|
2305
|
+
.includes(:places)
|
2306
|
+
.references(places: { ignore: LHC::NotFound })
|
2307
|
+
.find(123)
|
2308
|
+
```
|
2309
|
+
|
2310
|
+
```
|
2311
|
+
GET http://service/users/123
|
2312
|
+
{ "places": { "href": "http://service/users/123/places" } }
|
2313
|
+
|
2314
|
+
GET http://service/users/123/places
|
2315
|
+
{ "items": [
|
2316
|
+
{ "href": "http://service/places/1" },
|
2317
|
+
{ "href": "http://service/places/2" }
|
2318
|
+
] }
|
2319
|
+
|
2320
|
+
GET http://service/places/1
|
2321
|
+
200 { "name": "Casa Ferlin" }
|
2322
|
+
|
2323
|
+
GET http://service/places/2
|
2324
|
+
404 { "status": 404, "error": "not found" }
|
2325
|
+
```
|
2326
|
+
|
2327
|
+
```ruby
|
2328
|
+
user.places[1] # { "status": 404, "error": "not found" }
|
2329
|
+
```
|
2330
|
+
|
2331
|
+
In order to exclude items from a collection which where not based on successful responses, use `.compact` or `.compact!`:
|
2332
|
+
|
2333
|
+
```ruby
|
2334
|
+
# app/controllers/some_controller.rb
|
2335
|
+
|
2336
|
+
user = User
|
2337
|
+
.includes(:places)
|
2338
|
+
.references(places: { ignore: LHC::NotFound })
|
2339
|
+
.find(123)
|
2340
|
+
places = user.places.compact
|
2341
|
+
|
2342
|
+
places # { "items": [ { "href": "http://service/places/1", "name": "Casa Ferlin" } ] }
|
2343
|
+
```
|
2344
|
+
|
2293
2345
|
### Record batch processing
|
2294
2346
|
|
2295
2347
|
**Be careful using methods for batch processing. They could result in a lot of HTTP requests!**
|
@@ -2830,6 +2882,12 @@ expect(
|
|
2830
2882
|
).to eq {color: 'red', available: true}
|
2831
2883
|
```
|
2832
2884
|
|
2885
|
+
## Extended developer documentation
|
2886
|
+
|
2887
|
+
### Accessing data in LHS
|
2888
|
+
|
2889
|
+

|
2890
|
+
|
2833
2891
|
## License
|
2834
2892
|
|
2835
2893
|
[GNU General Public License Version 3.](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
Binary file
|
@@ -14,7 +14,7 @@ class LHS::Collection < LHS::Proxy
|
|
14
14
|
|
15
15
|
attr_accessor :raw
|
16
16
|
delegate :length, :size, :first, :last, :sample, :[], :present?, :blank?, :empty?,
|
17
|
-
:<<, :push,
|
17
|
+
:<<, :push, to: :raw
|
18
18
|
|
19
19
|
def initialize(raw, parent, record)
|
20
20
|
self.raw = raw
|
@@ -36,13 +36,37 @@ class LHS::Collection < LHS::Proxy
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
def compact
|
40
|
+
dup.tap do |collection|
|
41
|
+
collection.compact! if collection.raw.present?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def compact!
|
46
|
+
self.raw = raw.map do |item|
|
47
|
+
if item.is_a?(LHS::Data) && item._request && !item._request.response.success?
|
48
|
+
nil
|
49
|
+
else
|
50
|
+
cast_item(item)
|
51
|
+
end
|
52
|
+
end.compact
|
53
|
+
end
|
54
|
+
|
39
55
|
private
|
40
56
|
|
41
57
|
def cast_item(item)
|
42
|
-
record_by_href = LHS::Record.for_url(item[:href]) if item[:href]
|
43
58
|
data = LHS::Data.new(item, @parent, @record)
|
44
|
-
|
45
|
-
|
59
|
+
(record_by_href(item) || @record)&.new(data) || data
|
60
|
+
end
|
61
|
+
|
62
|
+
def record_by_href(item)
|
63
|
+
return if plain_value?(item) || item[:href].blank?
|
64
|
+
|
65
|
+
LHS::Record.for_url(item[:href])
|
66
|
+
end
|
67
|
+
|
68
|
+
def plain_value?(item)
|
69
|
+
item.is_a?(String) || item.is_a?(Numeric) || item.is_a?(TrueClass) || item.is_a?(FalseClass)
|
46
70
|
end
|
47
71
|
end
|
48
72
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support'
|
4
|
+
|
5
|
+
class LHS::Data
|
6
|
+
|
7
|
+
module Extend
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
# Extends already fetched data (self) with additionally
|
11
|
+
# fetched data (addition) using the given key
|
12
|
+
def extend!(addition, key)
|
13
|
+
addition = cast_relation_class_for_extension(addition, key)
|
14
|
+
if collection?
|
15
|
+
extend_collection!(addition, key)
|
16
|
+
elsif self[key]._raw.is_a? Array
|
17
|
+
extend_array!(addition, key)
|
18
|
+
elsif item?
|
19
|
+
extend_item!(addition, key)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def cast_relation_class_for_extension(addition, key)
|
26
|
+
return addition if _record.nil? || _record._relations.nil? || _record._relations[key].nil?
|
27
|
+
addition.becomes(_record._relations[key][:record_class_name].constantize, errors: addition.errors, warnings: addition.warnings)
|
28
|
+
end
|
29
|
+
|
30
|
+
def extend_collection!(addition, key)
|
31
|
+
map do |item|
|
32
|
+
item_raw = item._raw[key]
|
33
|
+
item_raw.blank? ? [nil] : item_raw
|
34
|
+
end
|
35
|
+
.flatten
|
36
|
+
.each_with_index do |item, index|
|
37
|
+
item_addition = addition[index]
|
38
|
+
next if item_addition.nil? || item.nil?
|
39
|
+
if item_addition._raw.is_a?(Array)
|
40
|
+
item[items_key] ||= []
|
41
|
+
item[items_key].concat(item_addition._raw)
|
42
|
+
else
|
43
|
+
item.merge! item_addition._raw
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def extend_array!(addition, key)
|
49
|
+
self[key].zip(addition) do |item, additional_item|
|
50
|
+
item._raw.merge!(additional_item._raw) if additional_item.present?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def extend_item!(addition, key)
|
55
|
+
return if addition.nil?
|
56
|
+
if addition.collection?
|
57
|
+
extend_item_with_collection!(addition, key)
|
58
|
+
else # simple case merges hash into hash
|
59
|
+
_raw[key.to_sym].merge!(addition._raw)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def extend_item_with_collection!(addition, key)
|
64
|
+
target = self[key]
|
65
|
+
if target._raw.is_a? Array
|
66
|
+
self[key] = addition.map(&:_raw)
|
67
|
+
else # hash with items
|
68
|
+
extend_item_with_hash_containing_items!(target, addition)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def extend_item_with_hash_containing_items!(target, addition)
|
73
|
+
LHS::Collection.nest(input: target._raw, value: [], record: self) # inits the nested collection
|
74
|
+
if LHS::Collection.access(input: target._raw, record: self).empty?
|
75
|
+
LHS::Collection.nest(input: target._raw, value: addition.reject { |item| item.nil? }, record: self)
|
76
|
+
else
|
77
|
+
LHS::Collection.access(input: target._raw, record: self).each_with_index do |item, index|
|
78
|
+
item.merge!(addition[index])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -98,74 +98,6 @@ class LHS::Record
|
|
98
98
|
)
|
99
99
|
end
|
100
100
|
|
101
|
-
# Extends existing raw data with additionaly fetched data
|
102
|
-
def extend_raw_data!(data, addition, key)
|
103
|
-
if data.collection?
|
104
|
-
extend_base_collection!(data, addition, key)
|
105
|
-
elsif data[key]._raw.is_a? Array
|
106
|
-
extend_base_array!(data, addition, key)
|
107
|
-
elsif data.item?
|
108
|
-
extend_base_item!(data, addition, key)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def extend_base_collection!(data, addition, key)
|
113
|
-
data.map do |item|
|
114
|
-
item_raw = item._raw[key]
|
115
|
-
item_raw.blank? ? [nil] : item_raw
|
116
|
-
end
|
117
|
-
.flatten
|
118
|
-
.each_with_index do |item, index|
|
119
|
-
item_addition = addition[index]
|
120
|
-
next if item_addition.nil? || item.nil?
|
121
|
-
if item_addition._raw.is_a?(Array)
|
122
|
-
extend_base_collection_with_array!(item, item_addition._raw)
|
123
|
-
else
|
124
|
-
item.merge! item_addition._raw
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
def extend_base_collection_with_array!(item, addition)
|
130
|
-
item[items_key] ||= []
|
131
|
-
item[items_key].concat(addition)
|
132
|
-
end
|
133
|
-
|
134
|
-
def extend_base_array!(data, addition, key)
|
135
|
-
data[key].zip(addition) do |item, additional_item|
|
136
|
-
item._raw.merge!(additional_item._raw) if additional_item.present?
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
def extend_base_item!(data, addition, key)
|
141
|
-
return if addition.nil?
|
142
|
-
if addition.collection?
|
143
|
-
extend_base_item_with_collection!(data, addition, key)
|
144
|
-
else # simple case merges hash into hash
|
145
|
-
data._raw[key.to_sym].merge!(addition._raw)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def extend_base_item_with_collection!(data, addition, key)
|
150
|
-
target = data[key]
|
151
|
-
if target._raw.is_a? Array
|
152
|
-
data[key] = addition.map(&:_raw)
|
153
|
-
else # hash with items
|
154
|
-
extend_base_item_with_hash_of_items!(target, addition)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
def extend_base_item_with_hash_of_items!(target, addition)
|
159
|
-
LHS::Collection.nest(input: target._raw, value: [], record: self)
|
160
|
-
if LHS::Collection.access(input: target._raw, record: self).empty?
|
161
|
-
LHS::Collection.nest(input: target._raw, value: addition.compact.map(&:_raw), record: self)
|
162
|
-
else
|
163
|
-
LHS::Collection.access(input: target._raw, record: self).each_with_index do |item, index|
|
164
|
-
item.merge!(addition[index])
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
101
|
def handle_includes(includes, data, references = {})
|
170
102
|
references ||= {}
|
171
103
|
if includes.is_a? Hash
|
@@ -187,8 +119,8 @@ class LHS::Record
|
|
187
119
|
options = options_for_data(data, included)
|
188
120
|
options = extend_with_reference(options, reference)
|
189
121
|
addition = load_include(options, data, sub_includes, reference)
|
190
|
-
|
191
|
-
expand_addition!(data, included,
|
122
|
+
data.extend!(addition, included)
|
123
|
+
expand_addition!(data, included, reference) unless expanded_data?(addition)
|
192
124
|
end
|
193
125
|
end
|
194
126
|
|
@@ -210,7 +142,7 @@ class LHS::Record
|
|
210
142
|
record = record_for_options(options) || self
|
211
143
|
options = convert_options_to_endpoints(options) if record_for_options(options)
|
212
144
|
expanded_data = record.request(options)
|
213
|
-
|
145
|
+
data.extend!(expanded_data, included)
|
214
146
|
end
|
215
147
|
|
216
148
|
def expanded_data?(addition)
|
data/lib/lhs/data.rb
CHANGED
@@ -6,6 +6,8 @@ class LHS::Data
|
|
6
6
|
'lhs/concerns/data/becomes'
|
7
7
|
autoload :Equality,
|
8
8
|
'lhs/concerns/data/equality'
|
9
|
+
autoload :Extend,
|
10
|
+
'lhs/concerns/data/extend'
|
9
11
|
autoload :Json,
|
10
12
|
'lhs/concerns/data/json'
|
11
13
|
autoload :ToHash,
|
@@ -13,6 +15,7 @@ class LHS::Data
|
|
13
15
|
|
14
16
|
include Becomes
|
15
17
|
include Equality
|
18
|
+
include Extend
|
16
19
|
include Json
|
17
20
|
include ToHash
|
18
21
|
include LHS::Inspect
|
@@ -30,6 +33,7 @@ class LHS::Data
|
|
30
33
|
self._proxy = proxy_from_input(input)
|
31
34
|
self._request = request
|
32
35
|
self._endpoint = endpoint
|
36
|
+
preserve_input_requests!(input)
|
33
37
|
end
|
34
38
|
|
35
39
|
# merging data
|
@@ -97,6 +101,17 @@ class LHS::Data
|
|
97
101
|
|
98
102
|
private
|
99
103
|
|
104
|
+
def preserve_input_requests!(input)
|
105
|
+
if input.is_a?(LHS::Data)
|
106
|
+
_request = input._request if _request.nil?
|
107
|
+
elsif input.is_a?(Array) && input.first.is_a?(LHS::Data)
|
108
|
+
input.each_with_index do |item, index|
|
109
|
+
next if item.nil?
|
110
|
+
self[index]._request = item._request
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
100
115
|
def collection_proxy?(input)
|
101
116
|
(input.is_a?(Hash) && LHS::Collection.access(input: input, record: _record)) ||
|
102
117
|
input.is_a?(Array) ||
|
data/lib/lhs/version.rb
CHANGED
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
describe LHS::Record do
|
6
|
+
before do
|
7
|
+
class Place < LHS::Record
|
8
|
+
endpoint 'http://datastore/places/{id}'
|
9
|
+
endpoint 'http://datastore/users/{user_id}/places/{id}'
|
10
|
+
|
11
|
+
def display_name
|
12
|
+
"*#{name}*"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class User < LHS::Record
|
17
|
+
endpoint 'http://datastore/users/{id}'
|
18
|
+
end
|
19
|
+
|
20
|
+
stub_request(:get, 'http://datastore/users/123')
|
21
|
+
.to_return(status: 200, body: {
|
22
|
+
href: 'http://datastore/users/123',
|
23
|
+
places: { href: 'http://datastore/users/123/places' }
|
24
|
+
}.to_json)
|
25
|
+
|
26
|
+
stub_request(:get, 'http://datastore/users/123/places?limit=100')
|
27
|
+
.to_return(status: 200, body: {
|
28
|
+
href: 'http://datastore/users/123/places?offset=0&limit=100',
|
29
|
+
items: [
|
30
|
+
{
|
31
|
+
href: 'http://datastore/users/123/places/789'
|
32
|
+
}, {
|
33
|
+
href: 'http://datastore/users/123/places/790'
|
34
|
+
}
|
35
|
+
],
|
36
|
+
total: 2,
|
37
|
+
offset: 0,
|
38
|
+
limit: 10
|
39
|
+
}.to_json)
|
40
|
+
|
41
|
+
stub_request(:get, 'http://datastore/users/123/places/789')
|
42
|
+
.to_return(
|
43
|
+
body: {
|
44
|
+
href: 'http://datastore/users/123/places/789?limit=100',
|
45
|
+
name: 'Mc Donalds'
|
46
|
+
}.to_json
|
47
|
+
)
|
48
|
+
|
49
|
+
stub_request(:get, 'http://datastore/users/123/places/790')
|
50
|
+
.to_return(
|
51
|
+
status: 404,
|
52
|
+
body: {
|
53
|
+
status: 404,
|
54
|
+
message: 'The requested resource does not exist.'
|
55
|
+
}.to_json
|
56
|
+
)
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
let(:places) do
|
61
|
+
User
|
62
|
+
.includes(:places)
|
63
|
+
.references(places: { ignore: LHC::NotFound })
|
64
|
+
.find('123')
|
65
|
+
.places
|
66
|
+
end
|
67
|
+
|
68
|
+
context '.compact' do
|
69
|
+
it 'removes linked resouces which could not get fetched' do
|
70
|
+
expect(places.compact.length).to eq 1
|
71
|
+
expect(places.length).not_to eq 1 # leaves the original intact
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'record casting' do
|
76
|
+
let(:expected_display_name) { '*Mc Donalds*' }
|
77
|
+
|
78
|
+
it 'finds the right record class' do
|
79
|
+
expect(places.first.display_name).to eq expected_display_name
|
80
|
+
expect(places.compact.map(&:display_name)).to eq [expected_display_name]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context '.compact!' do
|
85
|
+
it 'removes linked resouces which could not get fetched' do
|
86
|
+
expect(places.compact!.length).to eq 1
|
87
|
+
expect(places.length).to eq 1 # and changes the original intact
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
describe LHS::Record do
|
6
|
+
context 'includes all (expanded)' do
|
7
|
+
before do
|
8
|
+
class Record < LHS::Record
|
9
|
+
endpoint 'http://records/{id}'
|
10
|
+
end
|
11
|
+
|
12
|
+
stub_request(:get, "http://records/1")
|
13
|
+
.to_return(
|
14
|
+
body: {
|
15
|
+
car: { href: 'http://records/1/car' }
|
16
|
+
}.to_json
|
17
|
+
)
|
18
|
+
|
19
|
+
stub_request(:get, "http://records/1/car?color=blue&limit=100")
|
20
|
+
.to_return(
|
21
|
+
body: { href: 'http://records/cars/1' }.to_json
|
22
|
+
)
|
23
|
+
|
24
|
+
stub_request(:get, "http://records/cars/1?color=blue&limit=100")
|
25
|
+
.to_return(
|
26
|
+
body: { name: 'wrum wrum' }.to_json
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'expands linked resources and forwards proper reference' do
|
31
|
+
record = Record.includes(:car).references(car: { params: { color: :blue } }).find(1)
|
32
|
+
expect(
|
33
|
+
record.car.name
|
34
|
+
).to eq 'wrum wrum'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -8,6 +8,14 @@ describe LHS::Record do
|
|
8
8
|
class Customer < LHS::Record
|
9
9
|
endpoint 'http://datastore/customers/{id}'
|
10
10
|
end
|
11
|
+
|
12
|
+
class User < LHS::Record
|
13
|
+
endpoint 'http://datastore/users/{id}'
|
14
|
+
endpoint 'http://datastore/customers/{customer_id}/users/{id}'
|
15
|
+
def reversed_name
|
16
|
+
name.split.reverse.join(' ')
|
17
|
+
end
|
18
|
+
end
|
11
19
|
end
|
12
20
|
|
13
21
|
let!(:customer_request) do
|
@@ -18,6 +26,9 @@ describe LHS::Record do
|
|
18
26
|
},
|
19
27
|
'contact_addresses' => {
|
20
28
|
'href' => "http://datastore/contact_addresses"
|
29
|
+
},
|
30
|
+
'users' => {
|
31
|
+
'href' => 'http://datastore/customers/1/users'
|
21
32
|
}
|
22
33
|
}.to_json)
|
23
34
|
end
|
@@ -49,5 +60,37 @@ describe LHS::Record do
|
|
49
60
|
assert_requested(electronic_addresses_request)
|
50
61
|
assert_requested(contact_addresses_request)
|
51
62
|
end
|
63
|
+
|
64
|
+
describe 'mapping related classes correctly' do
|
65
|
+
before do
|
66
|
+
stub_request(:get, 'http://datastore/customers/1/users?limit=100').to_return(
|
67
|
+
status: 200,
|
68
|
+
body: {
|
69
|
+
href: 'http://datastore/customers/1/users?offset=0&limit=100',
|
70
|
+
items: [
|
71
|
+
{ href: 'http://datastore/customers/1/users/1' }
|
72
|
+
],
|
73
|
+
total: 1,
|
74
|
+
offset: 0,
|
75
|
+
limit: 10
|
76
|
+
}.to_json
|
77
|
+
)
|
78
|
+
|
79
|
+
stub_request(:get, 'http://datastore/customers/1/users/1')
|
80
|
+
.with(headers: { 'Authentication' => 'Bearer 123' })
|
81
|
+
.to_return(body: { href: 'http://datastore/users/1', name: 'Elizabeth Baker' }.to_json)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'maps correctly' do
|
85
|
+
users = Customer
|
86
|
+
.includes(:users)
|
87
|
+
.references(users: referencing_options)
|
88
|
+
.find(1)
|
89
|
+
.users
|
90
|
+
|
91
|
+
expect(users.first.reversed_name).to be_present
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
52
95
|
end
|
53
96
|
end
|
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: 24.
|
4
|
+
version: 24.1.2
|
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-
|
11
|
+
date: 2020-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -263,6 +263,7 @@ files:
|
|
263
263
|
- cider-ci/task_components/rspec.yml
|
264
264
|
- cider-ci/task_components/rubocop.yml
|
265
265
|
- cider-ci/task_components/ruby.yml
|
266
|
+
- docs/accessing-data-in-lhs.png
|
266
267
|
- friday.yml
|
267
268
|
- lhs.gemspec
|
268
269
|
- lib/lhs.rb
|
@@ -274,6 +275,7 @@ files:
|
|
274
275
|
- lib/lhs/concerns/configuration.rb
|
275
276
|
- lib/lhs/concerns/data/becomes.rb
|
276
277
|
- lib/lhs/concerns/data/equality.rb
|
278
|
+
- lib/lhs/concerns/data/extend.rb
|
277
279
|
- lib/lhs/concerns/data/json.rb
|
278
280
|
- lib/lhs/concerns/data/to_hash.rb
|
279
281
|
- lib/lhs/concerns/inspect.rb
|
@@ -471,6 +473,7 @@ files:
|
|
471
473
|
- spec/record/attribute_assignment_spec.rb
|
472
474
|
- spec/record/build_spec.rb
|
473
475
|
- spec/record/cast_nested_data_spec.rb
|
476
|
+
- spec/record/compact_spec.rb
|
474
477
|
- spec/record/create_spec.rb
|
475
478
|
- spec/record/creation_failed_spec.rb
|
476
479
|
- spec/record/custom_setters_spec.rb
|
@@ -501,6 +504,7 @@ files:
|
|
501
504
|
- spec/record/href_for_spec.rb
|
502
505
|
- spec/record/ignore_errors_spec.rb
|
503
506
|
- spec/record/immutable_chains_spec.rb
|
507
|
+
- spec/record/includes_expanded_spec.rb
|
504
508
|
- spec/record/includes_first_page_spec.rb
|
505
509
|
- spec/record/includes_spec.rb
|
506
510
|
- spec/record/includes_warning_spec.rb
|
@@ -699,6 +703,7 @@ test_files:
|
|
699
703
|
- spec/record/attribute_assignment_spec.rb
|
700
704
|
- spec/record/build_spec.rb
|
701
705
|
- spec/record/cast_nested_data_spec.rb
|
706
|
+
- spec/record/compact_spec.rb
|
702
707
|
- spec/record/create_spec.rb
|
703
708
|
- spec/record/creation_failed_spec.rb
|
704
709
|
- spec/record/custom_setters_spec.rb
|
@@ -729,6 +734,7 @@ test_files:
|
|
729
734
|
- spec/record/href_for_spec.rb
|
730
735
|
- spec/record/ignore_errors_spec.rb
|
731
736
|
- spec/record/immutable_chains_spec.rb
|
737
|
+
- spec/record/includes_expanded_spec.rb
|
732
738
|
- spec/record/includes_first_page_spec.rb
|
733
739
|
- spec/record/includes_spec.rb
|
734
740
|
- spec/record/includes_warning_spec.rb
|