remote_record 0.5.0 → 0.6.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 +102 -1
- data/lib/remote_record/base.rb +11 -3
- data/lib/remote_record/reference.rb +18 -0
- data/lib/remote_record/transformers/base.rb +4 -1
- data/lib/remote_record/transformers/snake_case.rb +8 -3
- data/lib/remote_record/version.rb +1 -1
- metadata +2 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8b0ea2bc5ed71919334a2a22d53f70a38ad06b116c7e76679e76bb0aeeb9ec9c
|
|
4
|
+
data.tar.gz: 4874762ea7e61fc354e99faa8d4cf6e79ba9b1451dcf5eefb029e2c173911b13
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 603cbf7ecd366f2e3ba00c0be7d1ef793a484948a4940ddae511ab7e99583620d405cee4068958099dcf44aec52bdcc0df612771fc9b9243db530b643d5f1220
|
|
7
|
+
data.tar.gz: d5edee74efd6afd30db89d237674c5deb6953279636accc3e22b28b95e866f769631dc4a13fa70b30982e8f1422f2707bd9ccac2b0b1bdca2de5824e21e9c732
|
data/README.md
CHANGED
|
@@ -124,6 +124,105 @@ caching by way of expiry or ETags, I recommend using `faraday-http-cache` for
|
|
|
124
124
|
your clients and setting `memoize` to `false`. Remote Record will eventually
|
|
125
125
|
gain support for caching.
|
|
126
126
|
|
|
127
|
+
### `remote_all` and `remote_where`
|
|
128
|
+
|
|
129
|
+
If you're able to fetch multiple records at once from the API, implement the
|
|
130
|
+
`self.all` method on your remote record class. This should return an array of
|
|
131
|
+
hashes that can be used to initialize a set of references.
|
|
132
|
+
|
|
133
|
+
This can optionally take a block
|
|
134
|
+
for authorization - note that it won't use the auth you've configured and that
|
|
135
|
+
you'll always have to supply that inline. For example:
|
|
136
|
+
|
|
137
|
+
```ruby
|
|
138
|
+
module RemoteRecord
|
|
139
|
+
module GitHub
|
|
140
|
+
# :nodoc:
|
|
141
|
+
class User < RemoteRecord::Base
|
|
142
|
+
def get
|
|
143
|
+
client.user(remote_resource_id)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def self.all
|
|
147
|
+
Octokit::Client.new(access_token: yield).users
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
private
|
|
151
|
+
|
|
152
|
+
def client
|
|
153
|
+
Octokit::Client.new(access_token: authorization)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Now you can call `remote_all` on remote reference classes that use
|
|
161
|
+
`RemoteRecord::GitHub::User`, like this:
|
|
162
|
+
|
|
163
|
+
```ruby
|
|
164
|
+
GitHub::UserReference.remote_all { GITHUB_PERSONAL_ACCESS_TOKEN }
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`remote_where` works in the same way, but with a parameter:
|
|
168
|
+
|
|
169
|
+
```ruby
|
|
170
|
+
module RemoteRecord
|
|
171
|
+
module GitHub
|
|
172
|
+
# :nodoc:
|
|
173
|
+
class User < RemoteRecord::Base
|
|
174
|
+
def get
|
|
175
|
+
client.user(remote_resource_id)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def self.all
|
|
179
|
+
Octokit::Client.new(access_token: yield).users
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def self.where(query)
|
|
183
|
+
Octokit::Client.new(access_token: yield).search_users(query)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
private
|
|
187
|
+
|
|
188
|
+
def client
|
|
189
|
+
Octokit::Client.new(access_token: authorization)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Now you can call `remote_where` on remote reference classes that use
|
|
197
|
+
`RemoteRecord::GitHub::User`, like this:
|
|
198
|
+
|
|
199
|
+
```ruby
|
|
200
|
+
GitHub::UserReference.remote_where('q=tom+repos:%3E42+followers:%3E1000') { GITHUB_PERSONAL_ACCESS_TOKEN }
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
It's recommended that you include something in `self.where` to filter incoming
|
|
204
|
+
params. Ideally, you want to expose an interface that's as ActiveRecord-like as
|
|
205
|
+
possible, e.g.:
|
|
206
|
+
|
|
207
|
+
```ruby
|
|
208
|
+
GitHub::UserReference.remote_where(q: 'tom', repos: '>42', followers: '>1000') { GITHUB_PERSONAL_ACCESS_TOKEN }
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
It's recommended that you write a `Transformer` to do this. Check out
|
|
212
|
+
`RemoteRecord::Transformers::SnakeCase` for an example.
|
|
213
|
+
|
|
214
|
+
### `initial_attrs`
|
|
215
|
+
|
|
216
|
+
Behind the scenes, `remote_all` initializes references with a set of
|
|
217
|
+
`initial_attrs`. You can do the same! If you've already fetched the data for an
|
|
218
|
+
object, just pass it to `new` for your reference class under the
|
|
219
|
+
`initial_attrs:` keyword parameter, like this:
|
|
220
|
+
|
|
221
|
+
```ruby
|
|
222
|
+
todo = { id: 1, title: 'Hello world' }
|
|
223
|
+
TodoReference.new(remote_resource_id: todo[:id], initial_attrs: todo)
|
|
224
|
+
```
|
|
225
|
+
|
|
127
226
|
### Forcing a fresh request
|
|
128
227
|
|
|
129
228
|
You might want to force a fresh request in some instances, even if you're using
|
|
@@ -131,4 +230,6 @@ You might want to force a fresh request in some instances, even if you're using
|
|
|
131
230
|
|
|
132
231
|
### Skip fetching
|
|
133
232
|
|
|
134
|
-
You might not want to make a request on initialize sometimes. In this case, pass
|
|
233
|
+
You might not want to make a request on initialize sometimes. In this case, pass
|
|
234
|
+
`fetching: false` to your query or `new` to make sure the resource isn't
|
|
235
|
+
fetched.
|
data/lib/remote_record/base.rb
CHANGED
|
@@ -9,10 +9,10 @@ module RemoteRecord
|
|
|
9
9
|
Config.defaults.merge(remote_record_class: self)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def initialize(reference, options)
|
|
12
|
+
def initialize(reference, options = default_config, initial_attrs = {})
|
|
13
13
|
@reference = reference
|
|
14
|
-
@options = options
|
|
15
|
-
@attrs = HashWithIndifferentAccess.new
|
|
14
|
+
@options = options
|
|
15
|
+
@attrs = HashWithIndifferentAccess.new(initial_attrs)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def method_missing(method_name, *_args, &_block)
|
|
@@ -29,6 +29,14 @@ module RemoteRecord
|
|
|
29
29
|
raise NotImplementedError.new, '#get should return a hash of data that represents the remote record.'
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
def self.all
|
|
33
|
+
raise NotImplementedError.new, '#all should return an array of hashes of data that represent remote records.'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.where(_params)
|
|
37
|
+
raise NotImplementedError.new, '#where should return an array of hashes of data that represent remote records.'
|
|
38
|
+
end
|
|
39
|
+
|
|
32
40
|
def fetch
|
|
33
41
|
@attrs.update(get)
|
|
34
42
|
end
|
|
@@ -23,19 +23,37 @@ module RemoteRecord
|
|
|
23
23
|
def remote_record_config
|
|
24
24
|
Config.new
|
|
25
25
|
end
|
|
26
|
+
|
|
27
|
+
def remote_all(&authz_proc)
|
|
28
|
+
remote_record_class.all(&authz_proc).map do |remote_resource|
|
|
29
|
+
where(remote_resource_id: remote_resource['id']).first_or_initialize(initial_attrs: remote_resource)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def remote_where(params, &authz_proc)
|
|
34
|
+
remote_record_class.where(params, &authz_proc).map do |remote_resource|
|
|
35
|
+
where(remote_resource_id: remote_resource['id']).first_or_initialize(initial_attrs: remote_resource)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
26
38
|
end
|
|
27
39
|
|
|
28
40
|
# rubocop:disable Metrics/BlockLength
|
|
29
41
|
included do
|
|
30
42
|
include ActiveSupport::Rescuable
|
|
31
43
|
attr_accessor :fetching
|
|
44
|
+
attr_accessor :initial_attrs
|
|
32
45
|
|
|
33
46
|
after_initialize do |reference|
|
|
34
47
|
reference.fetching = true if reference.fetching.nil?
|
|
48
|
+
reference.fetching = false if reference.initial_attrs.present?
|
|
35
49
|
config = reference.class.remote_record_class.default_config.merge(
|
|
36
50
|
reference.class.remote_record_config.to_h
|
|
37
51
|
)
|
|
38
52
|
reference.instance_variable_set('@remote_record_config', config)
|
|
53
|
+
reference.instance_variable_set('@instance',
|
|
54
|
+
@remote_record_config.remote_record_class.new(
|
|
55
|
+
self, @remote_record_config, reference.initial_attrs.presence || {}
|
|
56
|
+
))
|
|
39
57
|
reference.fetch_remote_resource
|
|
40
58
|
end
|
|
41
59
|
|
|
@@ -4,8 +4,11 @@ module RemoteRecord
|
|
|
4
4
|
module Transformers
|
|
5
5
|
# Base transformer class. Inherit from this and implement `#transform`.
|
|
6
6
|
class Base
|
|
7
|
-
def initialize(data)
|
|
7
|
+
def initialize(data, direction = :up)
|
|
8
|
+
raise ArgumentError, 'The direction should be one of :up or :down.' unless %i[up down].include? direction
|
|
9
|
+
|
|
8
10
|
@data = data
|
|
11
|
+
@direction = direction
|
|
9
12
|
end
|
|
10
13
|
|
|
11
14
|
def transform
|
|
@@ -15,14 +15,19 @@ module RemoteRecord
|
|
|
15
15
|
when Array
|
|
16
16
|
value.map { |v| convert_hash_keys(v) }
|
|
17
17
|
when Hash
|
|
18
|
-
Hash[value.map { |k, v| [
|
|
18
|
+
Hash[value.map { |k, v| [transform_key(k), convert_hash_keys(v)] }]
|
|
19
19
|
else
|
|
20
20
|
value
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
def
|
|
25
|
-
|
|
24
|
+
def transform_key(key)
|
|
25
|
+
case @direction
|
|
26
|
+
when :up
|
|
27
|
+
key.to_s.underscore.to_sym
|
|
28
|
+
when :down
|
|
29
|
+
key.to_s.camelize(:lower).to_sym
|
|
30
|
+
end
|
|
26
31
|
end
|
|
27
32
|
end
|
|
28
33
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: remote_record
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Simon Fish
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2021-
|
|
12
|
+
date: 2021-02-04 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activerecord
|
|
@@ -39,20 +39,6 @@ dependencies:
|
|
|
39
39
|
- - ">="
|
|
40
40
|
- !ruby/object:Gem::Version
|
|
41
41
|
version: '0'
|
|
42
|
-
- !ruby/object:Gem::Dependency
|
|
43
|
-
name: database_cleaner
|
|
44
|
-
requirement: !ruby/object:Gem::Requirement
|
|
45
|
-
requirements:
|
|
46
|
-
- - ">="
|
|
47
|
-
- !ruby/object:Gem::Version
|
|
48
|
-
version: '0'
|
|
49
|
-
type: :development
|
|
50
|
-
prerelease: false
|
|
51
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
52
|
-
requirements:
|
|
53
|
-
- - ">="
|
|
54
|
-
- !ruby/object:Gem::Version
|
|
55
|
-
version: '0'
|
|
56
42
|
- !ruby/object:Gem::Dependency
|
|
57
43
|
name: faraday
|
|
58
44
|
requirement: !ruby/object:Gem::Requirement
|