grape-roar 0.4.0 → 0.4.1
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/.gitignore +1 -0
- data/.rspec +1 -0
- data/.rubocop.yml +6 -2
- data/.rubocop_todo.yml +38 -9
- data/.travis.yml +29 -3
- data/Appraisals +9 -0
- data/CHANGELOG.md +10 -0
- data/Gemfile +6 -3
- data/README.md +218 -0
- data/Rakefile +3 -1
- data/gemfiles/with_activerecord.gemfile +22 -0
- data/gemfiles/with_mongoid.gemfile +22 -0
- data/grape-roar.gemspec +3 -0
- data/lib/grape-roar.rb +2 -0
- data/lib/grape/roar.rb +3 -0
- data/lib/grape/roar/decorator.rb +2 -0
- data/lib/grape/roar/extensions.rb +3 -0
- data/lib/grape/roar/extensions/relations.rb +23 -0
- data/lib/grape/roar/extensions/relations/adapters.rb +22 -0
- data/lib/grape/roar/extensions/relations/adapters/active_record.rb +35 -0
- data/lib/grape/roar/extensions/relations/adapters/base.rb +49 -0
- data/lib/grape/roar/extensions/relations/adapters/mongoid.rb +38 -0
- data/lib/grape/roar/extensions/relations/dsl_methods.rb +86 -0
- data/lib/grape/roar/extensions/relations/exceptions.rb +14 -0
- data/lib/grape/roar/extensions/relations/mapper.rb +89 -0
- data/lib/grape/roar/extensions/relations/validations.rb +5 -0
- data/lib/grape/roar/extensions/relations/validations/active_record.rb +67 -0
- data/lib/grape/roar/extensions/relations/validations/misc.rb +18 -0
- data/lib/grape/roar/extensions/relations/validations/mongoid.rb +88 -0
- data/lib/grape/roar/formatter.rb +2 -0
- data/lib/grape/roar/representer.rb +2 -0
- data/lib/grape/roar/version.rb +3 -1
- data/spec/config/mongoid.yml +6 -0
- data/spec/decorator_spec.rb +3 -1
- data/spec/extensions/relations/adapters/active_record_spec.rb +26 -0
- data/spec/extensions/relations/adapters/adapters_module_spec.rb +11 -0
- data/spec/extensions/relations/adapters/mongoid_spec.rb +26 -0
- data/spec/extensions/relations/dsl_methods_spec.rb +159 -0
- data/spec/extensions/relations/mapper_spec.rb +88 -0
- data/spec/extensions/relations/validations/active_record_spec.rb +46 -0
- data/spec/extensions/relations/validations/mongoid_spec.rb +88 -0
- data/spec/nested_representer_spec.rb +4 -13
- data/spec/present_with_spec.rb +3 -12
- data/spec/relations_spec.rb +76 -0
- data/spec/representer_spec.rb +3 -12
- data/spec/spec_helper.rb +15 -1
- data/spec/support/{article.rb → all/article.rb} +3 -1
- data/spec/support/{article_representer.rb → all/article_representer.rb} +2 -0
- data/spec/support/all/grape_app_context.rb +18 -0
- data/spec/support/{order.rb → all/order.rb} +3 -1
- data/spec/support/{order_representer.rb → all/order_representer.rb} +3 -1
- data/spec/support/{product.rb → all/product.rb} +2 -0
- data/spec/support/{product_representer.rb → all/product_representer.rb} +3 -1
- data/spec/support/{user.rb → all/user.rb} +2 -0
- data/spec/support/{user_representer.rb → all/user_representer.rb} +2 -0
- data/spec/support/mongoid/relational_models/cart.rb +7 -0
- data/spec/support/mongoid/relational_models/item.rb +7 -0
- data/spec/support/mongoid/relational_models/mongoid_cart_representer.rb +27 -0
- data/spec/support/mongoid/relational_models/mongoid_item_representer.rb +13 -0
- metadata +55 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 275fcec452345c4903f635a7a4d3cf87ac5f662a
|
4
|
+
data.tar.gz: fa6541ccfd36c24e05460da5a5eb9f3c7b837f7e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 773562779d81ea01fdeb3cf9b51ebc85d222f39945204424a917b07586bfa3a7b426b220ba5aa8b5c2daf16797e001c795cba7114c976aed348e98d4c929da77
|
7
|
+
data.tar.gz: 3b3f6c811fa78c9b3215fd2c100d1acbd94cd2fe53b00812837b0674284f0668e34a6c3c355adaab69085056439765d3772a50a4b5ef8510c88332599d959637
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
@@ -1,20 +1,49 @@
|
|
1
|
-
# This configuration was generated by
|
2
|
-
#
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2017-07-02 09:34:39 -0400 using RuboCop version 0.49.1.
|
3
4
|
# The point is for the user to remove these configuration records
|
4
5
|
# one by one as the offenses are removed from the code base.
|
5
6
|
# Note that changes in the inspected code, or installation of new
|
6
7
|
# versions of RuboCop, may require this file to be generated again.
|
7
8
|
|
8
|
-
# Offense count:
|
9
|
-
# Configuration parameters: AllowURI, URISchemes.
|
9
|
+
# Offense count: 7
|
10
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
11
|
+
# URISchemes: http, https
|
10
12
|
Metrics/LineLength:
|
11
|
-
Max:
|
13
|
+
Max: 108
|
12
14
|
|
13
|
-
# Offense count:
|
15
|
+
# Offense count: 14
|
14
16
|
Style/Documentation:
|
15
|
-
|
17
|
+
Exclude:
|
18
|
+
- 'spec/**/*'
|
19
|
+
- 'test/**/*'
|
20
|
+
- 'lib/grape/roar/decorator.rb'
|
21
|
+
- 'lib/grape/roar/extensions/relations.rb'
|
22
|
+
- 'lib/grape/roar/extensions/relations/adapters.rb'
|
23
|
+
- 'lib/grape/roar/extensions/relations/adapters/active_record.rb'
|
24
|
+
- 'lib/grape/roar/extensions/relations/adapters/base.rb'
|
25
|
+
- 'lib/grape/roar/extensions/relations/adapters/mongoid.rb'
|
26
|
+
- 'lib/grape/roar/extensions/relations/dsl_methods.rb'
|
27
|
+
- 'lib/grape/roar/extensions/relations/mapper.rb'
|
28
|
+
- 'lib/grape/roar/extensions/relations/validations/active_record.rb'
|
29
|
+
- 'lib/grape/roar/extensions/relations/validations/misc.rb'
|
30
|
+
- 'lib/grape/roar/extensions/relations/validations/mongoid.rb'
|
31
|
+
- 'lib/grape/roar/formatter.rb'
|
32
|
+
- 'lib/grape/roar/representer.rb'
|
16
33
|
|
17
34
|
# Offense count: 1
|
18
|
-
# Configuration parameters:
|
35
|
+
# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
|
36
|
+
# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
|
19
37
|
Style/FileName:
|
20
|
-
|
38
|
+
Exclude:
|
39
|
+
- 'lib/grape-roar.rb'
|
40
|
+
|
41
|
+
# Offense count: 3
|
42
|
+
# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.
|
43
|
+
# NamePrefix: is_, has_, have_
|
44
|
+
# NamePrefixBlacklist: is_, has_, have_
|
45
|
+
# NameWhitelist: is_a?
|
46
|
+
Style/PredicateName:
|
47
|
+
Exclude:
|
48
|
+
- 'spec/**/*'
|
49
|
+
- 'lib/grape/roar/extensions/relations/validations/active_record.rb'
|
data/.travis.yml
CHANGED
@@ -5,6 +5,32 @@ language: ruby
|
|
5
5
|
cache: bundler
|
6
6
|
|
7
7
|
rvm:
|
8
|
-
-
|
9
|
-
- 2.
|
10
|
-
|
8
|
+
- 2.4.1
|
9
|
+
- 2.3.4
|
10
|
+
|
11
|
+
gemfile:
|
12
|
+
- Gemfile
|
13
|
+
- gemfiles/with_activerecord.gemfile
|
14
|
+
- gemfiles/with_mongoid.gemfile
|
15
|
+
|
16
|
+
services:
|
17
|
+
- mongodb
|
18
|
+
- pg
|
19
|
+
|
20
|
+
matrix:
|
21
|
+
include:
|
22
|
+
- env: SPEC_OPTS="--tag active_record"
|
23
|
+
gemfile: gemfiles/with_activerecord.gemfile
|
24
|
+
rvm: 2.4.1
|
25
|
+
- env: SPEC_OPTS="--tag mongoid"
|
26
|
+
gemfile: gemfiles/with_mongoid.gemfile
|
27
|
+
rvm: 2.4.1
|
28
|
+
- env: SPEC_OPTS="--tag active_record"
|
29
|
+
gemfile: gemfiles/with_activerecord.gemfile
|
30
|
+
rvm: 2.3.4
|
31
|
+
- env: SPEC_OPTS="--tag mongoid"
|
32
|
+
gemfile: gemfiles/with_mongoid.gemfile
|
33
|
+
rvm: 2.3.4
|
34
|
+
|
35
|
+
|
36
|
+
script: bundle exec rake
|
data/Appraisals
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,17 +1,27 @@
|
|
1
|
+
0.4.1 (07/14/2017)
|
2
|
+
----
|
3
|
+
|
4
|
+
* [#22](https://github.com/ruby-grape/grape-roar/pull/22): Adds Grape::Roar::Extensions::Relations.
|
5
|
+
|
6
|
+
|
1
7
|
0.4.0 (02/18/2017)
|
2
8
|
------------------
|
9
|
+
|
3
10
|
* [#21](https://github.com/ruby-grape/grape-roar/pull/21): Fixes serialization issue due to [representable](https://github.com/trailblazer/representable) API change, drop support for Ruby < `2.1.0` - [@mach-kernel](https://github.com/mach-kernel).
|
4
11
|
|
12
|
+
|
5
13
|
0.3.0 (12/31/2014)
|
6
14
|
------------------
|
7
15
|
|
8
16
|
* Added support for Roar 1.0 - [@dblock](https://github.com/dblock).
|
9
17
|
|
18
|
+
|
10
19
|
0.2.0 (12/18/2014)
|
11
20
|
------------------
|
12
21
|
|
13
22
|
* [#10](https://github.com/ruby-grape/grape-roar/pull/10): Support for Roar decorator - [@sdbondi](https://github.com/sdbondi).
|
14
23
|
|
24
|
+
|
15
25
|
0.1.0 (7/17/2014)
|
16
26
|
-----------------
|
17
27
|
|
data/Gemfile
CHANGED
@@ -1,17 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source 'https://rubygems.org'
|
2
4
|
|
3
5
|
gemspec
|
4
6
|
|
5
7
|
group :development do
|
6
|
-
gem '
|
8
|
+
gem 'appraisal', '2.2.0'
|
7
9
|
end
|
8
10
|
|
9
11
|
group :test do
|
10
|
-
gem 'rspec', '~> 3.1'
|
11
12
|
gem 'rack-test'
|
13
|
+
gem 'rspec', '~> 3.1'
|
12
14
|
end
|
13
15
|
|
14
16
|
group :development, :test do
|
15
|
-
gem 'rubocop', '0.28.0'
|
16
17
|
gem 'nokogiri', '1.6.3.1'
|
18
|
+
gem 'rake', '~> 10.5.0'
|
19
|
+
gem 'rubocop', '0.49.1'
|
17
20
|
end
|
data/README.md
CHANGED
@@ -121,6 +121,224 @@ get 'products' do
|
|
121
121
|
end
|
122
122
|
```
|
123
123
|
|
124
|
+
### Relation Extensions
|
125
|
+
|
126
|
+
If you use either `ActiveRecord` or `Mongoid`, you can use the `Grape::Roar::Extensions::Relations` DSL to expose the relationships in between your models as a HAL response. The DSL methods used are the same regardless of what your ORM/ODM is, as long as there exists [an adapter for it](#designing-adapters).
|
127
|
+
|
128
|
+
#### Designing Representers
|
129
|
+
|
130
|
+
Arguments passed to `#relation` are forwarded to `roar`. Single member relations (e.g. `belongs_to`) are represented using `#property`, collections are represented using `#collection`; arguments provided to `#relation` will be passed through these methods (i.e. additional arguments [roar](https://github.com/trailblazer/roar) and [representable](http://trailblazer.to/gems/representable/3.0/api.html) accept).
|
131
|
+
|
132
|
+
A default base URI is constructed from a `Grape::Request` by concatenating the `#base_url` and `#script_name` properties. The resource path is extracted from the name of the relation.
|
133
|
+
|
134
|
+
Otherwise, the extensions attempt to look up the correct representer module/class for the objects (e.g. we infer the `extend` argument). You can always specify the correct representer to use on your own.
|
135
|
+
|
136
|
+
##### Example Models
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
class Item < ActiveRecord::Base
|
140
|
+
belongs_to :cart
|
141
|
+
end
|
142
|
+
|
143
|
+
class Cart < ActiveRecord::Base
|
144
|
+
has_many :items
|
145
|
+
end
|
146
|
+
```
|
147
|
+
|
148
|
+
##### Example Representers
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
class ItemEntity < Grape::Roar::Decorator
|
152
|
+
include Roar::JSON
|
153
|
+
include Roar::JSON::HAL
|
154
|
+
include Roar::Hypermedia
|
155
|
+
|
156
|
+
include Grape::Roar::Extensions::Relations
|
157
|
+
|
158
|
+
# Cart will be presented under the _embedded key
|
159
|
+
relation :belongs_to, :cart, embedded: true
|
160
|
+
|
161
|
+
link_self
|
162
|
+
end
|
163
|
+
|
164
|
+
class CartEntity < Grape::Roar::Decorator
|
165
|
+
include Roar::JSON
|
166
|
+
include Roar::JSON::HAL
|
167
|
+
include Roar::Hypermedia
|
168
|
+
|
169
|
+
include Grape::Roar::Extensions::Relations
|
170
|
+
|
171
|
+
# Items will be presented under the _links key
|
172
|
+
relation :has_many, :items, embedded: false
|
173
|
+
|
174
|
+
link_self
|
175
|
+
end
|
176
|
+
```
|
177
|
+
|
178
|
+
Although this example uses `Grape::Roar::Decorator`, you can also use a module as show in prior examples above. If doing so, you no longer have to mix in `Grape::Roar::Representer`.
|
179
|
+
|
180
|
+
##### Example Item
|
181
|
+
```javascript
|
182
|
+
{
|
183
|
+
"_embedded": {
|
184
|
+
"cart": {
|
185
|
+
"_links": {
|
186
|
+
"self": {
|
187
|
+
"href": "http://example.org/carts/1"
|
188
|
+
},
|
189
|
+
"items": [{
|
190
|
+
"href": "http://example.org/items/1"
|
191
|
+
}]
|
192
|
+
}
|
193
|
+
}
|
194
|
+
},
|
195
|
+
"_links": {
|
196
|
+
"self": {
|
197
|
+
"href": "http://example.org/items/1"
|
198
|
+
}
|
199
|
+
}
|
200
|
+
}
|
201
|
+
```
|
202
|
+
|
203
|
+
##### Example Cart
|
204
|
+
```javascript
|
205
|
+
{
|
206
|
+
"_links": {
|
207
|
+
"self": {
|
208
|
+
"href": "http://example.org/carts/1"
|
209
|
+
},
|
210
|
+
"items": [{
|
211
|
+
"href": "http://example.org/items/1"
|
212
|
+
}, {
|
213
|
+
"href": "http://example.org/items/2"
|
214
|
+
}, {
|
215
|
+
"href": "http://example.org/items/3"
|
216
|
+
}, {
|
217
|
+
"href": "http://example.org/items/4"
|
218
|
+
}, {
|
219
|
+
"href": "http://example.org/items/5"
|
220
|
+
}]
|
221
|
+
}
|
222
|
+
}
|
223
|
+
```
|
224
|
+
|
225
|
+
#### Errors
|
226
|
+
|
227
|
+
Should you incorrectly describe a relationship (e.g. you specify has_one but your model specifies has_many), an exception will be raised to notify you of the mismatch:
|
228
|
+
|
229
|
+
```ruby
|
230
|
+
Grape::Roar::Extensions::Relations::Exceptions::InvalidRelationError:
|
231
|
+
Expected Mongoid::Relations::Referenced::One, got Mongoid::Relations::Referenced::Many!
|
232
|
+
```
|
233
|
+
|
234
|
+
#### Change how URLs are presented
|
235
|
+
|
236
|
+
The `opts` hash below is the same one as shown in prior examples.
|
237
|
+
|
238
|
+
##### Override base URI mappings
|
239
|
+
```ruby
|
240
|
+
class BarEntity < Grape::Roar::Decorator
|
241
|
+
include Roar::JSON
|
242
|
+
include Roar::JSON::HAL
|
243
|
+
include Roar::Hypermedia
|
244
|
+
|
245
|
+
include Grape::Roar::Extensions::Relations
|
246
|
+
|
247
|
+
# This is our default implementation
|
248
|
+
map_base_url do |opts|
|
249
|
+
request = Grape::Request.new(opts[:env])
|
250
|
+
"#{request.base_url}#{request.script_name}"
|
251
|
+
end
|
252
|
+
|
253
|
+
relation :has_many, :bars, embedded: false
|
254
|
+
end
|
255
|
+
```
|
256
|
+
|
257
|
+
##### Override resource URI mappings
|
258
|
+
```ruby
|
259
|
+
class BarEntity < Grape::Roar::Decorator
|
260
|
+
include Roar::JSON
|
261
|
+
include Roar::JSON::HAL
|
262
|
+
include Roar::Hypermedia
|
263
|
+
|
264
|
+
include Grape::Roar::Extensions::Relations
|
265
|
+
|
266
|
+
# This is our default implementation
|
267
|
+
map_resource_path do |_opts, object, relation_name|
|
268
|
+
"#{relation_name}/#{object.id}"
|
269
|
+
end
|
270
|
+
|
271
|
+
relation :has_many, :bars, embedded: false
|
272
|
+
end
|
273
|
+
```
|
274
|
+
|
275
|
+
#### Designing Adapters
|
276
|
+
|
277
|
+
If you have custom domain objects, you can create an adapter to make your models compatible with the DSL methods. Below is an example of the `ActiveRecord` adapter.
|
278
|
+
|
279
|
+
##### Example: ActiveRecord Adapter
|
280
|
+
|
281
|
+
```ruby
|
282
|
+
module Extensions
|
283
|
+
module RelationalModels
|
284
|
+
module Adapter
|
285
|
+
class ActiveRecord < Base
|
286
|
+
include Validations::ActiveRecord
|
287
|
+
|
288
|
+
# We map your domain object to the correct adapter
|
289
|
+
# during runtime.
|
290
|
+
valid_for { |klass| klass < ::ActiveRecord::Base }
|
291
|
+
|
292
|
+
def collection_methods
|
293
|
+
@collection_methods ||= %i(has_many has_and_belongs_to_many)
|
294
|
+
end
|
295
|
+
|
296
|
+
def name_for_represented(represented)
|
297
|
+
klass_name = case represented
|
298
|
+
when ::ActiveRecord::Relation
|
299
|
+
represented.klass.name
|
300
|
+
else
|
301
|
+
represented.class.name
|
302
|
+
end
|
303
|
+
klass_name.demodulize.pluralize.downcase
|
304
|
+
end
|
305
|
+
|
306
|
+
def single_entity_methods
|
307
|
+
@single_entity_methods ||= %i(has_one belongs_to)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
```
|
314
|
+
|
315
|
+
##### Validations
|
316
|
+
|
317
|
+
Errors are handled by creating methods corresponding to those in `collection_methods` and `single_entity_methods`. For example, this is the validator for `belongs_to`:
|
318
|
+
|
319
|
+
```ruby
|
320
|
+
module ActiveRecord
|
321
|
+
include Validations::Misc
|
322
|
+
|
323
|
+
def belongs_to_valid?(relation)
|
324
|
+
relation = klass.reflections[relation]
|
325
|
+
|
326
|
+
return true if relation.is_a?(
|
327
|
+
::ActiveRecord::Reflection::BelongsToReflection
|
328
|
+
)
|
329
|
+
|
330
|
+
# Provided by Validations::Misc
|
331
|
+
invalid_relation(
|
332
|
+
::ActiveRecord::Reflection::BelongsToReflection,
|
333
|
+
relation.class
|
334
|
+
)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
```
|
338
|
+
|
339
|
+
After writing your validation methods, just mix them into your adapter. You can choose to not write validation methods; they are only invoked if your adapter responds to them.
|
340
|
+
|
341
|
+
|
124
342
|
Contributing
|
125
343
|
------------
|
126
344
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "activerecord", ">= 4.0.0", require: "active_record"
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem "appraisal", "2.2.0"
|
9
|
+
end
|
10
|
+
|
11
|
+
group :test do
|
12
|
+
gem "rack-test"
|
13
|
+
gem "rspec", "~> 3.1"
|
14
|
+
end
|
15
|
+
|
16
|
+
group :development, :test do
|
17
|
+
gem "nokogiri", "1.6.3.1"
|
18
|
+
gem "rake", "~> 10.5.0"
|
19
|
+
gem "rubocop", "0.49.1"
|
20
|
+
end
|
21
|
+
|
22
|
+
gemspec path: "../"
|