lhs 5.0.4 → 5.1.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 +26 -0
- data/lib/lhs/concerns/item/destroy.rb +3 -2
- data/lib/lhs/concerns/item/save.rb +5 -4
- data/lib/lhs/concerns/item/update.rb +10 -7
- data/lib/lhs/concerns/item/validation.rb +9 -6
- data/lib/lhs/concerns/record/chainable.rb +164 -0
- data/lib/lhs/concerns/record/create.rb +4 -4
- data/lib/lhs/concerns/record/find.rb +9 -7
- data/lib/lhs/concerns/record/find_by.rb +7 -6
- data/lib/lhs/record.rb +4 -4
- data/lib/lhs/version.rb +1 -1
- data/spec/record/options_spec.rb +160 -0
- metadata +5 -3
- data/lib/lhs/concerns/record/where.rb +0 -65
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb3fe085cc83710039d972594c9f7f8d85adbe23
|
4
|
+
data.tar.gz: dd26184f622e4ac0cf4ed64caf80ba767604cb83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad8fcbb562a7401d884ebc8104b8b7354466b075245a164623c391ef63a37e8d855dafc30a26b906a9d36820e1edc228d815b1daefb730016f41630bd8c75de4
|
7
|
+
data.tar.gz: b9d6c74ea6abc94fe4dbab55531fc3285a1b76cefc04d6152e29bc3498f93dadffd7e16be4fd921d6073c1918d45c6d7c7b02dc9a45bea4837a67e0aa4cecb2f
|
data/README.md
CHANGED
@@ -156,6 +156,32 @@ If no record is found, `nil` is returned.
|
|
156
156
|
|
157
157
|
`first!` raises LHC::NotFound if nothing was found.
|
158
158
|
|
159
|
+
## Request based options
|
160
|
+
|
161
|
+
You can apply options to the request chain. Those options will be forwarded to the request perfomed by the chain/query.
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
options = { auth: { bearer: '123456' } }
|
165
|
+
|
166
|
+
AuthenticatedRecord = Record.options(options)
|
167
|
+
|
168
|
+
blue_records = AuthenticatedRecord.where(color: 'blue')
|
169
|
+
active_records = AuthenticatedRecord.where(active: true)
|
170
|
+
|
171
|
+
AuthenticatedRecord.create(color: 'red')
|
172
|
+
|
173
|
+
record = AuthenticatedRecord.find(123)
|
174
|
+
# Find resolves the current query and applies all options from the chain
|
175
|
+
# All further requests are made from scratch and not based on the previous options
|
176
|
+
record.name = 'Walter'
|
177
|
+
|
178
|
+
authenticated_record = record.options(options)
|
179
|
+
authenticated_record.valid?
|
180
|
+
authenticated_record.save
|
181
|
+
authenticated_record.destroy
|
182
|
+
authenticated_record.update(name: 'Steve')
|
183
|
+
```
|
184
|
+
|
159
185
|
## Batch processing
|
160
186
|
|
161
187
|
**Be careful using methods for batch processing. They could result in a lot of HTTP requests!**
|
@@ -6,8 +6,9 @@ class LHS::Item < LHS::Proxy
|
|
6
6
|
module Destroy
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
|
-
def destroy
|
10
|
-
|
9
|
+
def destroy(options = {})
|
10
|
+
options ||= {}
|
11
|
+
_data._request = _data.class.request(options.merge(method: :delete, url: href))._request
|
11
12
|
_data
|
12
13
|
end
|
13
14
|
end
|
@@ -6,14 +6,15 @@ class LHS::Item < LHS::Proxy
|
|
6
6
|
module Save
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
|
-
def save
|
10
|
-
save!
|
9
|
+
def save(options = nil)
|
10
|
+
save!(options)
|
11
11
|
rescue LHC::Error => e
|
12
12
|
self.errors = LHS::Errors.new(e.response)
|
13
13
|
false
|
14
14
|
end
|
15
15
|
|
16
|
-
def save!
|
16
|
+
def save!(options = {})
|
17
|
+
options ||= {}
|
17
18
|
record = _data.class
|
18
19
|
data = _data._raw.dup
|
19
20
|
if href.present?
|
@@ -24,7 +25,7 @@ class LHS::Item < LHS::Proxy
|
|
24
25
|
endpoint.remove_interpolated_params!(data)
|
25
26
|
end
|
26
27
|
|
27
|
-
data = record.request(method: :post, url: url, body: data.to_json, headers: { 'Content-Type' => 'application/json' })
|
28
|
+
data = record.request(options.merge(method: :post, url: url, body: data.to_json, headers: { 'Content-Type' => 'application/json' }))
|
28
29
|
_data.merge_raw!(data)
|
29
30
|
true
|
30
31
|
end
|
@@ -6,20 +6,23 @@ class LHS::Item < LHS::Proxy
|
|
6
6
|
module Update
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
|
-
def update(params)
|
10
|
-
update!(params)
|
9
|
+
def update(params, options = nil)
|
10
|
+
update!(params, options)
|
11
11
|
rescue LHC::Error => e
|
12
12
|
self.errors = LHS::Errors.new(e.response)
|
13
13
|
false
|
14
14
|
end
|
15
15
|
|
16
|
-
def update!(params)
|
16
|
+
def update!(params, options = {})
|
17
|
+
options ||= {}
|
17
18
|
_data.merge_raw!(LHS::Data.new(params, _data.parent, _data.class))
|
18
19
|
response_data = _data.class.request(
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
options.merge(
|
21
|
+
method: :post,
|
22
|
+
url: href,
|
23
|
+
body: _data.to_json,
|
24
|
+
headers: { 'Content-Type' => 'application/json' }
|
25
|
+
)
|
23
26
|
)
|
24
27
|
_data.merge_raw!(response_data)
|
25
28
|
true
|
@@ -5,7 +5,8 @@ class LHS::Item < LHS::Proxy
|
|
5
5
|
module Validation
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
|
-
def valid?
|
8
|
+
def valid?(options = {})
|
9
|
+
options ||= {}
|
9
10
|
self.errors = nil
|
10
11
|
fail 'No validation endpoint found!' unless validation_endpoint
|
11
12
|
record = LHS::Record.for_url(validation_endpoint.url)
|
@@ -13,11 +14,13 @@ class LHS::Item < LHS::Proxy
|
|
13
14
|
params = validation_endpoint.options.fetch(:params, {}).merge(validation_params)
|
14
15
|
begin
|
15
16
|
record.request(
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
options.merge(
|
18
|
+
url: validation_endpoint.url,
|
19
|
+
method: :post,
|
20
|
+
params: params,
|
21
|
+
body: _data.to_json,
|
22
|
+
headers: { 'Content-Type' => 'application/json' }
|
23
|
+
)
|
21
24
|
)
|
22
25
|
true
|
23
26
|
rescue LHC::Error => e
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
class LHS::Record
|
4
|
+
|
5
|
+
module Chainable
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
# You can start new option chains for already fetched records (needed for save, update, valid etc.)
|
9
|
+
def options(hash = nil)
|
10
|
+
Chain.new(self.class, Option.new(hash), self)
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
def where(hash = nil)
|
15
|
+
Chain.new(self, Parameter.new(hash))
|
16
|
+
end
|
17
|
+
|
18
|
+
def options(hash = nil)
|
19
|
+
Chain.new(self, Option.new(hash))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Link: A part of a chain
|
24
|
+
class Link
|
25
|
+
def initialize(hash = nil)
|
26
|
+
@hash = hash
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_hash
|
30
|
+
@hash
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Parameter: Part of the chain that will be forwarded to the endpoint as parameter
|
35
|
+
class Parameter < Link
|
36
|
+
end
|
37
|
+
|
38
|
+
# Option: Part of the chain that will be used to configure the communication with the endpoint
|
39
|
+
class Option < Link
|
40
|
+
end
|
41
|
+
|
42
|
+
# A sequence of links
|
43
|
+
class Chain
|
44
|
+
|
45
|
+
# Instance exec is required for scope chains
|
46
|
+
delegated_methods = Object.instance_methods - [:instance_exec]
|
47
|
+
delegate(*delegated_methods, to: :resolve)
|
48
|
+
|
49
|
+
def initialize(record_class, link, record = nil)
|
50
|
+
@record_class = record_class
|
51
|
+
@record = record
|
52
|
+
@chain = [link].compact
|
53
|
+
end
|
54
|
+
|
55
|
+
def create(data = {})
|
56
|
+
@record_class.create(data, chain_options)
|
57
|
+
end
|
58
|
+
|
59
|
+
def create!(data = {})
|
60
|
+
@record_class.create!(data, chain_options)
|
61
|
+
end
|
62
|
+
|
63
|
+
def save!(options = nil)
|
64
|
+
options ||= {}
|
65
|
+
@record.save!(chain_options.merge(options))
|
66
|
+
end
|
67
|
+
|
68
|
+
def save(options = nil)
|
69
|
+
options ||= {}
|
70
|
+
@record.save(chain_options.merge(options))
|
71
|
+
end
|
72
|
+
|
73
|
+
def destroy(options = nil)
|
74
|
+
options ||= {}
|
75
|
+
@record.destroy(chain_options.merge(options))
|
76
|
+
end
|
77
|
+
|
78
|
+
def update(data = {}, options = nil)
|
79
|
+
options ||= {}
|
80
|
+
@record.update(data, chain_options.merge(options))
|
81
|
+
end
|
82
|
+
|
83
|
+
def update!(data = {}, options = nil)
|
84
|
+
options ||= {}
|
85
|
+
@record.update!(data, chain_options.merge(options))
|
86
|
+
end
|
87
|
+
|
88
|
+
def valid?(options = nil)
|
89
|
+
options ||= {}
|
90
|
+
@record.valid?(chain_options.merge(options))
|
91
|
+
end
|
92
|
+
alias validate valid?
|
93
|
+
|
94
|
+
def where(hash = nil)
|
95
|
+
push Parameter.new(hash)
|
96
|
+
end
|
97
|
+
|
98
|
+
def options(hash = nil)
|
99
|
+
push Option.new(hash)
|
100
|
+
end
|
101
|
+
|
102
|
+
def find(args)
|
103
|
+
@record_class.find(args, chain_options)
|
104
|
+
end
|
105
|
+
|
106
|
+
def find_by(params = {})
|
107
|
+
@record_class.find_by(params, chain_options)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Returns a hash of where conditions
|
111
|
+
def where_values_hash
|
112
|
+
chain_parameters
|
113
|
+
end
|
114
|
+
|
115
|
+
# Returns a hash of options
|
116
|
+
def option_values_hash
|
117
|
+
chain_options
|
118
|
+
end
|
119
|
+
|
120
|
+
protected
|
121
|
+
|
122
|
+
def method_missing(name, *args, &block)
|
123
|
+
scope = @record_class.scopes[name]
|
124
|
+
return instance_exec(*args, &scope) if scope
|
125
|
+
resolve.send(name, *args, &block)
|
126
|
+
end
|
127
|
+
|
128
|
+
def respond_to_missing?(name, include_all = false)
|
129
|
+
@record_class.scopes[name] ||
|
130
|
+
resolve.respond_to?(name, include_all)
|
131
|
+
end
|
132
|
+
|
133
|
+
def resolve
|
134
|
+
@resolved ||= @record_class.new(
|
135
|
+
@record_class.request(chain_options.merge(params: chain_parameters))
|
136
|
+
)
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def push(link)
|
142
|
+
@chain += [link].compact
|
143
|
+
self
|
144
|
+
end
|
145
|
+
|
146
|
+
def chain_parameters
|
147
|
+
merge_links @chain.select { |link| link.is_a? Parameter }
|
148
|
+
end
|
149
|
+
|
150
|
+
def chain_options
|
151
|
+
merge_links @chain.select { |link| link.is_a? Option }
|
152
|
+
end
|
153
|
+
|
154
|
+
def merge_links(links)
|
155
|
+
hash = {}
|
156
|
+
links.each do |link|
|
157
|
+
next if link.to_hash.blank?
|
158
|
+
hash.deep_merge!(link.to_hash)
|
159
|
+
end
|
160
|
+
hash
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -6,15 +6,15 @@ class LHS::Record
|
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
8
|
module ClassMethods
|
9
|
-
def create(data = {})
|
9
|
+
def create(data = {}, options = nil)
|
10
10
|
record = new(data)
|
11
|
-
record.save
|
11
|
+
record.save(options)
|
12
12
|
record
|
13
13
|
end
|
14
14
|
|
15
|
-
def create!(data = {})
|
15
|
+
def create!(data = {}, options = nil)
|
16
16
|
record = new(data)
|
17
|
-
record.save!
|
17
|
+
record.save!(options)
|
18
18
|
record
|
19
19
|
end
|
20
20
|
end
|
@@ -7,12 +7,12 @@ class LHS::Record
|
|
7
7
|
|
8
8
|
module ClassMethods
|
9
9
|
# Find a single uniqe record
|
10
|
-
def find(args)
|
10
|
+
def find(args, options = nil)
|
11
11
|
data =
|
12
12
|
if args.is_a? Hash
|
13
|
-
find_with_parameters(args)
|
13
|
+
find_with_parameters(args, options)
|
14
14
|
else
|
15
|
-
find_by_id(args)
|
15
|
+
find_by_id(args, options)
|
16
16
|
end
|
17
17
|
return data unless data._record
|
18
18
|
data._record.new(data)
|
@@ -20,8 +20,9 @@ class LHS::Record
|
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
|
-
def find_with_parameters(params)
|
24
|
-
|
23
|
+
def find_with_parameters(params, options = {})
|
24
|
+
options ||= {}
|
25
|
+
data = request(options.merge(params: params))
|
25
26
|
if data._proxy.is_a?(LHS::Collection)
|
26
27
|
fail LHC::NotFound.new('Requested unique item. Multiple were found.', data._request.response) if data.length > 1
|
27
28
|
data.first || fail(LHC::NotFound.new('No item was found.', data._request.response))
|
@@ -30,8 +31,9 @@ class LHS::Record
|
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
33
|
-
def find_by_id(id)
|
34
|
-
|
34
|
+
def find_by_id(id, options = {})
|
35
|
+
options ||= {}
|
36
|
+
request(options.merge(params: { id: id }))
|
35
37
|
end
|
36
38
|
end
|
37
39
|
end
|
@@ -7,22 +7,23 @@ class LHS::Record
|
|
7
7
|
|
8
8
|
module ClassMethods
|
9
9
|
# Fetch some record by parameters
|
10
|
-
def find_by(params = {})
|
11
|
-
_find_by(params)
|
10
|
+
def find_by(params = {}, options = nil)
|
11
|
+
_find_by(params, options)
|
12
12
|
rescue LHC::NotFound
|
13
13
|
nil
|
14
14
|
end
|
15
15
|
|
16
16
|
# Raise if no record was found
|
17
|
-
def find_by!(params = {})
|
18
|
-
_find_by(params)
|
17
|
+
def find_by!(params = {}, options = nil)
|
18
|
+
_find_by(params, options)
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
|
-
def _find_by(params)
|
23
|
+
def _find_by(params, options = {})
|
24
|
+
options ||= {}
|
24
25
|
params = params.dup.merge(limit: 1)
|
25
|
-
data = request(params: params)
|
26
|
+
data = request(options.merge(params: params))
|
26
27
|
if data._proxy.is_a?(LHS::Collection)
|
27
28
|
data.first || fail(LHC::NotFound.new('No item was found.', data._request.response))
|
28
29
|
else
|
data/lib/lhs/record.rb
CHANGED
@@ -3,19 +3,19 @@ Dir[File.dirname(__FILE__) + '/concerns/record/*.rb'].each { |file| require file
|
|
3
3
|
class LHS::Record
|
4
4
|
include All
|
5
5
|
include Batch
|
6
|
+
include Chainable
|
6
7
|
include Configuration
|
7
8
|
include Create
|
8
9
|
include Endpoints
|
9
10
|
include Find
|
10
11
|
include FindBy
|
11
12
|
include First
|
13
|
+
include Includes
|
12
14
|
include Mapping
|
13
15
|
include Model
|
14
|
-
include Includes
|
15
|
-
include Scope
|
16
|
-
include Request
|
17
|
-
include Where
|
18
16
|
include Pagination
|
17
|
+
include Request
|
18
|
+
include Scope
|
19
19
|
|
20
20
|
delegate :_proxy, to: :_data
|
21
21
|
delegate :_endpoint, to: :_data
|
data/lib/lhs/version.rb
CHANGED
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe LHS::Record do
|
4
|
+
let(:datastore) do
|
5
|
+
'http://datastore/v2'
|
6
|
+
end
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
LHC.config.placeholder('datastore', datastore)
|
10
|
+
class Record < LHS::Record
|
11
|
+
endpoint ':datastore/records', validates: true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:options) { { auth: { bearer: '123' }, validates: true } }
|
16
|
+
let(:params) { { name: 'Steve' } }
|
17
|
+
|
18
|
+
context 'options' do
|
19
|
+
it 'is possible to pass options to the chain' do
|
20
|
+
expect(LHC).to receive(:request)
|
21
|
+
.with(options.merge(params: params).merge(url: 'http://datastore/v2/records'))
|
22
|
+
.and_call_original
|
23
|
+
stub_request(:get, "http://datastore/v2/records?name=Steve")
|
24
|
+
.to_return(body: { name: "Steve", is: 'awesome' }.to_json)
|
25
|
+
Record.options(options).where(params).first
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'applies last one wins also to the options' do
|
29
|
+
stub_request(:get, "http://datastore/v2/records")
|
30
|
+
.to_return(body: { name: "Steve", is: 'awesome' }.to_json)
|
31
|
+
expect(LHC).to receive(:request)
|
32
|
+
.with(options.merge(url: 'http://datastore/v2/records'))
|
33
|
+
.and_call_original
|
34
|
+
Record.options(auth: 'basic').options(options).where.first
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'is also applicable to find' do
|
38
|
+
stub_request(:get, 'http://datastore/v2/records?id=123').to_return(body: {}.to_json)
|
39
|
+
expect(LHC).to receive(:request)
|
40
|
+
.with(options.merge(params: { id: "123" }, url: 'http://datastore/v2/records'))
|
41
|
+
.and_call_original
|
42
|
+
Record.options(options).find('123')
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'is also applicable to find_by' do
|
46
|
+
stub_request(:get, 'http://datastore/v2/records?id=123&limit=1').to_return(body: {}.to_json)
|
47
|
+
expect(LHC).to receive(:request)
|
48
|
+
.with(options.merge(params: { id: "123", limit: 1 }, url: 'http://datastore/v2/records'))
|
49
|
+
.and_call_original
|
50
|
+
Record.options(options).find_by(id: '123')
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'is also applicable to first' do
|
54
|
+
stub_request(:get, 'http://datastore/v2/records').to_return(body: {}.to_json)
|
55
|
+
expect(LHC).to receive(:request)
|
56
|
+
.with(options.merge(url: 'http://datastore/v2/records'))
|
57
|
+
.and_call_original
|
58
|
+
Record.options(options).first
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'is also applicable to create' do
|
62
|
+
stub_request(:post, 'http://datastore/v2/records').to_return(body: {}.to_json)
|
63
|
+
expect(LHC).to receive(:request)
|
64
|
+
.with(options.merge(method: :post, url: "http://datastore/v2/records", body: "{\"name\":\"Steve\"}", headers: { 'Content-Type' => 'application/json' }))
|
65
|
+
.and_call_original
|
66
|
+
Record.options(options).create(name: 'Steve')
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'actions on single records' do
|
70
|
+
let!(:record) do
|
71
|
+
stub_request(:get, "http://datastore/v2/records?id=123").to_return(body: { href: 'http://datastore/v2/records/123' }.to_json)
|
72
|
+
Record.find(123)
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'save' do
|
76
|
+
before(:each) do
|
77
|
+
stub_request(:post, 'http://datastore/v2/records/123').to_return(body: {}.to_json)
|
78
|
+
expect(LHC).to receive(:request)
|
79
|
+
.with(options.merge(method: :post, url: "http://datastore/v2/records/123", body: "{\"href\":\"http://datastore/v2/records/123\"}", headers: { "Content-Type" => "application/json" }))
|
80
|
+
.and_call_original
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'applies directly on save' do
|
84
|
+
record.save(options)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'applies directly on save!' do
|
88
|
+
record.save!(options)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'applies chaining them with save' do
|
92
|
+
record.options(options).save
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'applies chaining them with save!' do
|
96
|
+
record.options(options).save!
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'destroy' do
|
101
|
+
before(:each) do
|
102
|
+
stub_request(:delete, 'http://datastore/v2/records/123').to_return(body: {}.to_json)
|
103
|
+
expect(LHC).to receive(:request)
|
104
|
+
.with(options.merge(method: :delete, url: "http://datastore/v2/records/123"))
|
105
|
+
.and_call_original
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'applies directly on destroy' do
|
109
|
+
record.destroy(options)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'applies chaining them with destroy' do
|
113
|
+
record.options(options).destroy
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'update' do
|
118
|
+
before(:each) do
|
119
|
+
stub_request(:post, "http://datastore/v2/records/123").to_return(body: {}.to_json)
|
120
|
+
expect(LHC).to receive(:request)
|
121
|
+
.with(options.merge(method: :post, url: "http://datastore/v2/records/123", body: "{\"href\":\"http://datastore/v2/records/123\",\"name\":\"steve\"}", headers: { "Content-Type" => "application/json" }))
|
122
|
+
.and_call_original
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'applies directly on update' do
|
126
|
+
record.update({ name: 'steve' }, options)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'applies directly on update!' do
|
130
|
+
record.update!({ name: 'steve' }, options)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'applies chaining them with update' do
|
134
|
+
record.options(options).update(name: 'steve')
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'applies chaining them with update!' do
|
138
|
+
record.options(options).update!(name: 'steve')
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'valid' do
|
143
|
+
before(:each) do
|
144
|
+
stub_request(:post, 'http://datastore/v2/records?persist=false').to_return(body: {}.to_json)
|
145
|
+
expect(LHC).to receive(:request)
|
146
|
+
.with(options.merge(url: ':datastore/records', method: :post, params: { persist: false }, body: "{\"href\":\"http://datastore/v2/records/123\"}", headers: { "Content-Type" => "application/json" }))
|
147
|
+
.and_call_original
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'applies directly on valid' do
|
151
|
+
record.valid?(options)
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'applies chaining them with valid' do
|
155
|
+
record.options(options).valid?
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
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: 5.0
|
4
|
+
version: 5.1.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: 2016-05-
|
11
|
+
date: 2016-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lhc
|
@@ -186,6 +186,7 @@ files:
|
|
186
186
|
- lib/lhs/concerns/item/validation.rb
|
187
187
|
- lib/lhs/concerns/record/all.rb
|
188
188
|
- lib/lhs/concerns/record/batch.rb
|
189
|
+
- lib/lhs/concerns/record/chainable.rb
|
189
190
|
- lib/lhs/concerns/record/configuration.rb
|
190
191
|
- lib/lhs/concerns/record/create.rb
|
191
192
|
- lib/lhs/concerns/record/endpoints.rb
|
@@ -198,7 +199,6 @@ files:
|
|
198
199
|
- lib/lhs/concerns/record/pagination.rb
|
199
200
|
- lib/lhs/concerns/record/request.rb
|
200
201
|
- lib/lhs/concerns/record/scope.rb
|
201
|
-
- lib/lhs/concerns/record/where.rb
|
202
202
|
- lib/lhs/data.rb
|
203
203
|
- lib/lhs/endpoint.rb
|
204
204
|
- lib/lhs/errors.rb
|
@@ -296,6 +296,7 @@ files:
|
|
296
296
|
- spec/record/mapping_spec.rb
|
297
297
|
- spec/record/model_name_spec.rb
|
298
298
|
- spec/record/new_spec.rb
|
299
|
+
- spec/record/options_spec.rb
|
299
300
|
- spec/record/paginatable_collection_spec.rb
|
300
301
|
- spec/record/pagination_spec.rb
|
301
302
|
- spec/record/persisted_spec.rb
|
@@ -428,6 +429,7 @@ test_files:
|
|
428
429
|
- spec/record/mapping_spec.rb
|
429
430
|
- spec/record/model_name_spec.rb
|
430
431
|
- spec/record/new_spec.rb
|
432
|
+
- spec/record/options_spec.rb
|
431
433
|
- spec/record/paginatable_collection_spec.rb
|
432
434
|
- spec/record/pagination_spec.rb
|
433
435
|
- spec/record/persisted_spec.rb
|
@@ -1,65 +0,0 @@
|
|
1
|
-
require 'active_support'
|
2
|
-
|
3
|
-
class LHS::Record
|
4
|
-
|
5
|
-
module Where
|
6
|
-
extend ActiveSupport::Concern
|
7
|
-
|
8
|
-
class WhereChain
|
9
|
-
|
10
|
-
# Instance exec is required for scope chains
|
11
|
-
delegated_methods = Object.instance_methods - [:instance_exec]
|
12
|
-
delegate(*delegated_methods, to: :resolve)
|
13
|
-
|
14
|
-
def initialize(record, parameters)
|
15
|
-
@record = record
|
16
|
-
@chain = [parameters].compact
|
17
|
-
end
|
18
|
-
|
19
|
-
def where(parameters)
|
20
|
-
@chain += [parameters].compact
|
21
|
-
self
|
22
|
-
end
|
23
|
-
|
24
|
-
# Returns a hash of where conditions
|
25
|
-
def where_values_hash
|
26
|
-
merged_parameters
|
27
|
-
end
|
28
|
-
|
29
|
-
protected
|
30
|
-
|
31
|
-
def method_missing(name, *args, &block)
|
32
|
-
scope = @record.scopes[name]
|
33
|
-
return instance_exec(*args, &scope) if scope
|
34
|
-
resolve.send(name, *args, &block)
|
35
|
-
end
|
36
|
-
|
37
|
-
def respond_to_missing?(name, include_all = false)
|
38
|
-
@record.scopes[name] ||
|
39
|
-
resolve.respond_to?(name, include_all)
|
40
|
-
end
|
41
|
-
|
42
|
-
def resolve
|
43
|
-
@resolved ||= @record.new(
|
44
|
-
@record.request(params: merged_parameters)
|
45
|
-
)
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def merged_parameters
|
51
|
-
merged_parameters = {}
|
52
|
-
@chain.each do |parameter|
|
53
|
-
merged_parameters.deep_merge!(parameter)
|
54
|
-
end
|
55
|
-
merged_parameters
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
module ClassMethods
|
60
|
-
def where(parameters = nil)
|
61
|
-
WhereChain.new(self, parameters)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|