jsonapi-serializable 0.1.1.beta3 → 0.1.1.beta4
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 +42 -95
- data/lib/jsonapi/serializable/abstract_resource.rb +122 -0
- data/lib/jsonapi/serializable/abstract_resource_dsl.rb +130 -0
- data/lib/jsonapi/serializable/error.rb +5 -5
- data/lib/jsonapi/serializable/link.rb +4 -4
- data/lib/jsonapi/serializable/relationship.rb +23 -12
- data/lib/jsonapi/serializable/relationship_dsl.rb +25 -22
- data/lib/jsonapi/serializable/renderer.rb +6 -5
- data/lib/jsonapi/serializable/resource.rb +3 -97
- data/lib/jsonapi/serializable/resource_builder.rb +16 -15
- data/lib/jsonapi/serializable/resource_dsl.rb +13 -110
- data/lib/jsonapi/serializable.rb +0 -1
- metadata +4 -4
- data/lib/jsonapi/serializable/model.rb +0 -12
- data/lib/jsonapi/serializable/model_dsl.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b7a55ca51fb13e04ac2c96153ea3558aef19d35
|
4
|
+
data.tar.gz: 7a378903d6206bdc7cb203bd47a5ec415034ec87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a29424f72a6a0170319503da5f7aa3a8bb62633cdcd496d0e0ae89f5a7431fe6b9dd763e8ff6fe44aa2823fa897c191434f6fe211836cc3133dcc57654ebb065
|
7
|
+
data.tar.gz: 18ead5e2f56d6cad50e432c4d09f5f7590df9d27e1b52348d0d3ca1f72e8efd22065d0c763cd3e1b8340ab692fb7c1fb8633674f572dc5dfa9eeb5475a19d66f
|
data/README.md
CHANGED
@@ -11,11 +11,8 @@ the [jsonapi-renderer](https://github.com/jsonapi-rb/renderer) gem.
|
|
11
11
|
|
12
12
|
- [Installation](#installation)
|
13
13
|
- [Usage](#usage)
|
14
|
-
- [Example for Model-based Resources](#example-for-model-based-resources)
|
15
|
-
- [Example for General Resources](#example-for-general-resources)
|
16
14
|
- [Documentation](#documentation)
|
17
15
|
- [`JSONAPI::Serializable::Resource` DSL](#jsonapiserializableresource-dsl)
|
18
|
-
- [`JSONAPI::Serializable::Model` DSL](#jsonapiserializablemodel-dsl)
|
19
16
|
- [`JSONAPI::Serializable::Relationship` DSL](#jsonapiserializablerelationship-dsl)
|
20
17
|
- [`JSONAPI::Serializable::Link` DSL](#jsonapiserializablelink-dsl)
|
21
18
|
- [`JSONAPI::Serializable::Error` DSL](#jsonapiserializableerror-dsl)
|
@@ -44,26 +41,22 @@ require 'jsonapi/serializable'
|
|
44
41
|
|
45
42
|
Then, define some resource classes:
|
46
43
|
|
47
|
-
### Example for Model-based Resources
|
48
|
-
|
49
|
-
For resources that are simple representations of models, the DSL is simplified:
|
50
|
-
|
51
44
|
```ruby
|
52
|
-
class PostResource < JSONAPI::Serializable::
|
45
|
+
class PostResource < JSONAPI::Serializable::Resource
|
53
46
|
type 'posts'
|
54
47
|
|
55
48
|
attribute :title
|
56
49
|
|
57
50
|
attribute :date do
|
58
|
-
@
|
51
|
+
@object.created_at
|
59
52
|
end
|
60
53
|
|
61
|
-
has_one :author,
|
54
|
+
has_one :author, 'V2::SerializableUser' do
|
62
55
|
link(:self) do
|
63
|
-
href @
|
56
|
+
href @url_helpers.link_for_rel('posts', @object.id, 'author')
|
64
57
|
meta link_meta: 'some meta'
|
65
58
|
end
|
66
|
-
link(:related) { @
|
59
|
+
link(:related) { @url_helpers.link_for_res('users', @object.author.id) }
|
67
60
|
meta do
|
68
61
|
{ relationship_meta: 'some meta' }
|
69
62
|
end
|
@@ -76,78 +69,24 @@ class PostResource < JSONAPI::Serializable::Model
|
|
76
69
|
end
|
77
70
|
|
78
71
|
link(:self) do
|
79
|
-
@
|
72
|
+
@url_helpers.link_for_res('posts', @object.id)
|
80
73
|
end
|
81
74
|
end
|
82
75
|
```
|
83
76
|
|
84
|
-
Then,
|
85
|
-
```ruby
|
86
|
-
# post = some post model
|
87
|
-
# UrlHelper is some helper class
|
88
|
-
resource = PostResource.new(model: post, url_helper: UrlHelper)
|
89
|
-
document = JSONAPI.render(data: resource)
|
90
|
-
```
|
91
|
-
|
92
|
-
### Example for General Resources
|
93
|
-
|
94
|
-
In case your resource is not a simple representation of one of your models,
|
95
|
-
the more general `JSONAPI::Serializable::Resource` class can be used.
|
96
|
-
|
97
|
-
```ruby
|
98
|
-
class PostResource < JSONAPI::Serializable::Resource
|
99
|
-
type 'posts'
|
100
|
-
|
101
|
-
id do
|
102
|
-
@post.id.to_s
|
103
|
-
end
|
104
|
-
|
105
|
-
attribute :title do
|
106
|
-
@post.title
|
107
|
-
end
|
108
|
-
|
109
|
-
attribute :date do
|
110
|
-
@post.date
|
111
|
-
end
|
112
|
-
|
113
|
-
relationship :author do
|
114
|
-
link(:self) do
|
115
|
-
href @url_helper.link_for_rel('posts', @post.id, 'author')
|
116
|
-
meta link_meta: 'some meta'
|
117
|
-
end
|
118
|
-
link(:related) { @url_helper.link_for_res('users', @post.author.id) }
|
119
|
-
data do
|
120
|
-
if @post.author.nil?
|
121
|
-
nil
|
122
|
-
else
|
123
|
-
UserResource.new(user: @post.author, url_helper: @url_helper)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
meta do
|
127
|
-
{ relationship_meta: 'some meta' }
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
meta do
|
132
|
-
{ resource_meta: 'some meta' }
|
133
|
-
end
|
134
|
-
|
135
|
-
link(:self) do
|
136
|
-
@url_helper.link_for_res('posts', @post.id)
|
137
|
-
end
|
138
|
-
end
|
139
|
-
```
|
140
|
-
Finally, build your resources from your models and render them:
|
77
|
+
Then, render your resources:
|
141
78
|
```ruby
|
142
|
-
# post
|
143
|
-
#
|
144
|
-
|
145
|
-
|
79
|
+
# `post` is some `Post` object
|
80
|
+
# `UrlHelpers` is some helper class
|
81
|
+
document = JSONAPI::Serializable::Renderer.render(
|
82
|
+
post,
|
83
|
+
expose: { url_helpers: UrlHelpers.new }
|
84
|
+
)
|
146
85
|
```
|
147
86
|
|
148
87
|
## Documentation
|
149
88
|
|
150
|
-
### `JSONAPI::Serializable::
|
89
|
+
### `JSONAPI::Serializable::AbstractResource` DSL
|
151
90
|
|
152
91
|
+ `#initialize(hash)`
|
153
92
|
|
@@ -156,8 +95,8 @@ variables within all DSLs.
|
|
156
95
|
|
157
96
|
Example:
|
158
97
|
```ruby
|
159
|
-
SerializablePost.new(post: post,
|
160
|
-
# => You can then use @post and @
|
98
|
+
SerializablePost.new(post: post, url_helpers: url_helpers)
|
99
|
+
# => You can then use @post and @url_helpers from within the DSL.
|
161
100
|
```
|
162
101
|
|
163
102
|
+ `::type(value = nil, &block)`
|
@@ -191,13 +130,13 @@ the [`JSONAPI::Serializable::Relationship` DSL](#jsonapiserializablerelationship
|
|
191
130
|
Example:
|
192
131
|
```ruby
|
193
132
|
relationship :comments do
|
194
|
-
|
133
|
+
resources do
|
195
134
|
@post.comments.map do |c|
|
196
|
-
SerializableComment.new(comment: c,
|
135
|
+
SerializableComment.new(comment: c, url_helpers: @url_helpers)
|
197
136
|
end
|
198
137
|
end
|
199
138
|
link :self do
|
200
|
-
@
|
139
|
+
@url_helpers.link_for_post_comments(post_id: @post.id)
|
201
140
|
end
|
202
141
|
meta do
|
203
142
|
{ count: @post.comments.count }
|
@@ -232,25 +171,25 @@ meta do
|
|
232
171
|
end
|
233
172
|
```
|
234
173
|
|
235
|
-
### `JSONAPI::Serializable::
|
174
|
+
### `JSONAPI::Serializable::Resource` DSL
|
236
175
|
|
237
|
-
This class is a subclass of `JSONAPI::Serializable::
|
176
|
+
This class is a subclass of `JSONAPI::Serializable::AbstractResource` with a more
|
238
177
|
convenient DSL tailored for resources that are direct representation of some
|
239
178
|
business models.
|
240
179
|
|
241
180
|
+ `#initialize(hash)`
|
242
181
|
|
243
|
-
See `JSONAPI::Serializable::
|
182
|
+
See `JSONAPI::Serializable::AbstractResource` DSL.
|
244
183
|
|
245
184
|
The model is expected to be provided in the hash with the key `:model`.
|
246
185
|
|
247
186
|
+ `::type(value = nil, &block)`
|
248
187
|
|
249
|
-
See `JSONAPI::Serializable::
|
188
|
+
See `JSONAPI::Serializable::AbstractResource` DSL.
|
250
189
|
|
251
190
|
+ `::id(&block)`
|
252
191
|
|
253
|
-
See `JSONAPI::Serializable::
|
192
|
+
See `JSONAPI::Serializable::AbstractResource` DSL.
|
254
193
|
|
255
194
|
Defaults to:
|
256
195
|
```ruby
|
@@ -259,7 +198,7 @@ id { @model.id }
|
|
259
198
|
|
260
199
|
+ `::attribute(key, &block)`
|
261
200
|
|
262
|
-
See `JSONAPI::Serializable::
|
201
|
+
See `JSONAPI::Serializable::AbstractResource` DSL.
|
263
202
|
|
264
203
|
Defaults to the following when no block is provided:
|
265
204
|
```ruby
|
@@ -268,6 +207,10 @@ attribute key do
|
|
268
207
|
end
|
269
208
|
```
|
270
209
|
|
210
|
+
+ `::attributes(*keys)`
|
211
|
+
|
212
|
+
Define multiple attributes.
|
213
|
+
|
271
214
|
+ `::has_one(key, resource_klass = nil, &block)`
|
272
215
|
|
273
216
|
Define a `has_one` relationship on the resource.
|
@@ -296,28 +239,28 @@ end
|
|
296
239
|
|
297
240
|
+ `::relationship(key, &block)`
|
298
241
|
|
299
|
-
See `JSONAPI::Serializable::
|
242
|
+
See `JSONAPI::Serializable::AbstractResource` DSL.
|
300
243
|
|
301
244
|
+ `::link(key, &block)`
|
302
245
|
|
303
|
-
See `JSONAPI::Serializable::
|
246
|
+
See `JSONAPI::Serializable::AbstractResource` DSL.
|
304
247
|
|
305
248
|
+ `::meta(value = nil, &block)`
|
306
249
|
|
307
|
-
See `JSONAPI::Serializable::
|
250
|
+
See `JSONAPI::Serializable::AbstractResource` DSL.
|
308
251
|
|
309
252
|
### `JSONAPI::Serializable::Relationship` DSL
|
310
253
|
|
311
|
-
+ `::
|
254
|
+
+ `::resources(resource_class = nil, &block)`
|
312
255
|
|
313
|
-
NOTE: This section is outdated. It is still valid, but the
|
314
|
-
much more flexible.
|
256
|
+
NOTE: This section is outdated. It is still valid, but the resources method is
|
257
|
+
now much more flexible.
|
315
258
|
|
316
259
|
Defines the related serializable resources for the relationship.
|
317
260
|
|
318
261
|
Example:
|
319
262
|
```ruby
|
320
|
-
|
263
|
+
resources do
|
321
264
|
if @post.author.nil?
|
322
265
|
nil
|
323
266
|
else
|
@@ -326,17 +269,21 @@ data do
|
|
326
269
|
end
|
327
270
|
```
|
328
271
|
|
272
|
+
+ `::data(&block)`
|
273
|
+
|
274
|
+
Explicitly define linkage data (optional).
|
275
|
+
|
329
276
|
+ `::link(key, &block)`
|
330
277
|
|
331
278
|
Define a relationship-level link.
|
332
279
|
|
333
|
-
See `JSONAPI::Serializable::
|
280
|
+
See `JSONAPI::Serializable::AbstractResource` DSL.
|
334
281
|
|
335
282
|
+ `::meta(value = nil, &block)`
|
336
283
|
|
337
284
|
Define some relationship-level meta member.
|
338
285
|
|
339
|
-
See `JSONAPI::Serializable::
|
286
|
+
See `JSONAPI::Serializable::AbstractResource` DSL.
|
340
287
|
|
341
288
|
### `JSONAPI::Serializable::Link` DSL
|
342
289
|
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'jsonapi/serializable/link'
|
2
|
+
require 'jsonapi/serializable/relationship'
|
3
|
+
require 'jsonapi/serializable/abstract_resource_dsl'
|
4
|
+
|
5
|
+
module JSONAPI
|
6
|
+
module Serializable
|
7
|
+
class AbstractResource
|
8
|
+
include AbstractResourceDSL
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr_accessor :id_block,
|
12
|
+
:type_val, :type_block,
|
13
|
+
:meta_val, :meta_block,
|
14
|
+
:attribute_blocks,
|
15
|
+
:relationship_blocks,
|
16
|
+
:link_blocks
|
17
|
+
end
|
18
|
+
|
19
|
+
self.attribute_blocks = {}
|
20
|
+
self.relationship_blocks = {}
|
21
|
+
self.link_blocks = {}
|
22
|
+
|
23
|
+
def self.inherited(klass)
|
24
|
+
super
|
25
|
+
klass.type_val = type_val
|
26
|
+
klass.type_block = type_block
|
27
|
+
klass.id_block = id_block
|
28
|
+
klass.meta_val = meta_val
|
29
|
+
klass.meta_block = meta_block
|
30
|
+
klass.attribute_blocks = attribute_blocks.dup
|
31
|
+
klass.relationship_blocks = relationship_blocks.dup
|
32
|
+
klass.link_blocks = link_blocks.dup
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(exposures = {})
|
36
|
+
exposures.each { |k, v| instance_variable_set("@#{k}", v) }
|
37
|
+
@_exposures = exposures
|
38
|
+
@_type = _type
|
39
|
+
@_id = _id
|
40
|
+
@_attributes = {}
|
41
|
+
@_relationships = _relationships
|
42
|
+
@_meta = _meta
|
43
|
+
@_links = _links
|
44
|
+
end
|
45
|
+
|
46
|
+
def as_jsonapi(fields: nil, include: [])
|
47
|
+
{}.tap do |hash|
|
48
|
+
hash[:id] = @_id
|
49
|
+
hash[:type] = @_type
|
50
|
+
hash[:links] = @_links if @_links.any?
|
51
|
+
hash[:meta] = @_meta unless @_meta.nil?
|
52
|
+
|
53
|
+
attrs = requested_attributes(fields)
|
54
|
+
hash[:attributes] = attrs if attrs.any?
|
55
|
+
|
56
|
+
rels = requested_relationships(fields, include)
|
57
|
+
hash[:relationships] = rels if rels.any?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def jsonapi_type
|
62
|
+
@_type
|
63
|
+
end
|
64
|
+
|
65
|
+
def jsonapi_id
|
66
|
+
@_id
|
67
|
+
end
|
68
|
+
|
69
|
+
def jsonapi_related(include)
|
70
|
+
@_relationships
|
71
|
+
.select { |k, _| include.include?(k) }
|
72
|
+
.each_with_object({}) { |(k, v), h| h[k] = v.related_resources }
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def _type
|
78
|
+
self.class.type_val || instance_eval(&self.class.type_block)
|
79
|
+
end
|
80
|
+
|
81
|
+
def _id
|
82
|
+
instance_eval(&self.class.id_block)
|
83
|
+
end
|
84
|
+
|
85
|
+
def _relationships
|
86
|
+
self.class.relationship_blocks
|
87
|
+
.each_with_object({}) do |(k, v), h|
|
88
|
+
h[k] = Relationship.new(@_exposures, &v)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def _meta
|
93
|
+
if self.class.meta_block
|
94
|
+
instance_eval(&self.class.meta_block)
|
95
|
+
else
|
96
|
+
self.class.meta_val
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def _links
|
101
|
+
self.class.link_blocks
|
102
|
+
.each_with_object({}) do |(k, v), h|
|
103
|
+
h[k] = Link.as_jsonapi(@_exposures, &v)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def requested_attributes(fields)
|
108
|
+
self.class.attribute_blocks
|
109
|
+
.select { |k, _| fields.nil? || fields.include?(k) }
|
110
|
+
.each_with_object({}) { |(k, v), h| h[k] = instance_eval(&v) }
|
111
|
+
end
|
112
|
+
|
113
|
+
def requested_relationships(fields, include)
|
114
|
+
@_relationships
|
115
|
+
.select { |k, _| fields.nil? || fields.include?(k) }
|
116
|
+
.each_with_object({}) do |(k, v), h|
|
117
|
+
h[k] = v.as_jsonapi(include.include?(k))
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module JSONAPI
|
2
|
+
module Serializable
|
3
|
+
module AbstractResourceDSL
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
# @overload type(value)
|
10
|
+
# Declare the JSON API type of this resource.
|
11
|
+
# @param [String] value The value of the type.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# type 'users'
|
15
|
+
#
|
16
|
+
# @overload type(value)
|
17
|
+
# Declare the JSON API type of this resource.
|
18
|
+
# @yieldreturn [String] The value of the type.
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# type { @user.admin? ? "admin" : "users" }
|
22
|
+
def type(value = nil, &block)
|
23
|
+
self.type_val = value
|
24
|
+
self.type_block = block
|
25
|
+
end
|
26
|
+
|
27
|
+
# Declare the JSON API id of this resource.
|
28
|
+
#
|
29
|
+
# @yieldreturn [String] The id of the resource.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# id { @user.id.to_s }
|
33
|
+
def id(&block)
|
34
|
+
self.id_block = block
|
35
|
+
end
|
36
|
+
|
37
|
+
# @overload meta(value)
|
38
|
+
# Declare the meta information for this resource.
|
39
|
+
# @param [Hash] value The meta information hash.
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
# meta key: value
|
43
|
+
#
|
44
|
+
# @overload meta(&block)
|
45
|
+
# Declare the meta information for this resource.
|
46
|
+
# @yieldreturn [String] The meta information hash.
|
47
|
+
# @example
|
48
|
+
# meta do
|
49
|
+
# { key: value }
|
50
|
+
# end
|
51
|
+
def meta(value = nil, &block)
|
52
|
+
self.meta_val = value
|
53
|
+
self.meta_block = block
|
54
|
+
end
|
55
|
+
|
56
|
+
# Declare an attribute for this resource.
|
57
|
+
#
|
58
|
+
# @param [Symbol] name The key of the attribute.
|
59
|
+
# @yieldreturn [Hash, String, nil] The block to compute the value.
|
60
|
+
#
|
61
|
+
# @example
|
62
|
+
# attribute(:name) { @user.name }
|
63
|
+
def attribute(name, &block)
|
64
|
+
attribute_blocks[name] = block
|
65
|
+
end
|
66
|
+
|
67
|
+
# Declare a relationship for this resource. The properties of the
|
68
|
+
# relationship are set by providing a block in which the DSL methods
|
69
|
+
# of +JSONAPI::Serializable::Relationship+ are called.
|
70
|
+
# @see JSONAPI::Serializable::Relationship
|
71
|
+
#
|
72
|
+
# @param [Symbol] name The key of the relationship.
|
73
|
+
#
|
74
|
+
# @example
|
75
|
+
# relationship :posts do
|
76
|
+
# data { @user.posts.map { |p| PostResource.new(post: p) } }
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# @example
|
80
|
+
# relationship :author do
|
81
|
+
# data do
|
82
|
+
# @post.author && UserResource.new(user: @post.author)
|
83
|
+
# end
|
84
|
+
# linkage_data do
|
85
|
+
# { type: 'users', id: @post.author_id }
|
86
|
+
# end
|
87
|
+
# link(:self) do
|
88
|
+
# "http://api.example.com/posts/#{@post.id}/relationships/author"
|
89
|
+
# end
|
90
|
+
# link(:related) do
|
91
|
+
# "http://api.example.com/posts/#{@post.id}/author"
|
92
|
+
# end
|
93
|
+
# meta do
|
94
|
+
# { author_online: @post.author.online? }
|
95
|
+
# end
|
96
|
+
# end
|
97
|
+
def relationship(name, &block)
|
98
|
+
relationship_blocks[name] = block
|
99
|
+
end
|
100
|
+
alias has_many relationship
|
101
|
+
alias has_one relationship
|
102
|
+
alias belongs_to relationship
|
103
|
+
|
104
|
+
# Declare a link for this resource. The properties of the link are set
|
105
|
+
# by providing a block in which the DSL methods of
|
106
|
+
# +JSONAPI::Serializable::Link+ are called, or the value of the link
|
107
|
+
# is returned directly.
|
108
|
+
# @see JSONAPI::Serialiable::Link
|
109
|
+
#
|
110
|
+
# @param [Symbol] name The key of the link.
|
111
|
+
# @yieldreturn [Hash, String, nil] The block to compute the value, if
|
112
|
+
# any.
|
113
|
+
#
|
114
|
+
# @example
|
115
|
+
# link(:self) do
|
116
|
+
# "http://api.example.com/users/#{@user.id}"
|
117
|
+
# end
|
118
|
+
#
|
119
|
+
# @example
|
120
|
+
# link(:self) do
|
121
|
+
# href "http://api.example.com/users/#{@user.id}"
|
122
|
+
# meta is_self: true
|
123
|
+
# end
|
124
|
+
def link(name, &block)
|
125
|
+
link_blocks[name] = block
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -40,9 +40,9 @@ module JSONAPI
|
|
40
40
|
klass.link_blocks = self.class.link_blocks.dup
|
41
41
|
end
|
42
42
|
|
43
|
-
def initialize(
|
44
|
-
@
|
45
|
-
|
43
|
+
def initialize(exposures = {})
|
44
|
+
@_exposures = exposures
|
45
|
+
exposures.each { |k, v| instance_variable_set("@#{k}", v) }
|
46
46
|
end
|
47
47
|
|
48
48
|
def as_jsonapi
|
@@ -58,12 +58,12 @@ module JSONAPI
|
|
58
58
|
|
59
59
|
def links
|
60
60
|
@_links ||= self.class.link_blocks.each_with_object({}) do |(k, v), h|
|
61
|
-
h[k] = Link.as_jsonapi(@
|
61
|
+
h[k] = Link.as_jsonapi(@_exposures, v)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
65
|
def source
|
66
|
-
@_source ||= ErrorSource.as_jsonapi(@
|
66
|
+
@_source ||= ErrorSource.as_jsonapi(@_exposures,
|
67
67
|
self.class.source_block)
|
68
68
|
end
|
69
69
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module JSONAPI
|
2
2
|
module Serializable
|
3
3
|
class Link
|
4
|
-
def self.as_jsonapi(
|
5
|
-
new(
|
4
|
+
def self.as_jsonapi(exposures = {}, &block)
|
5
|
+
new(exposures, &block).as_jsonapi
|
6
6
|
end
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
|
8
|
+
def initialize(exposures = {}, &block)
|
9
|
+
exposures.each { |k, v| instance_variable_set("@#{k}", v) }
|
10
10
|
static_value = instance_eval(&block)
|
11
11
|
if static_value.is_a?(Hash)
|
12
12
|
@_hash = static_value
|
@@ -6,31 +6,42 @@ module JSONAPI
|
|
6
6
|
class Relationship
|
7
7
|
include RelationshipDSL
|
8
8
|
|
9
|
-
def initialize(
|
10
|
-
|
11
|
-
@
|
12
|
-
@_links
|
9
|
+
def initialize(exposures = {}, &block)
|
10
|
+
exposures.each { |k, v| instance_variable_set("@#{k}", v) }
|
11
|
+
@_exposures = exposures
|
12
|
+
@_links = {}
|
13
13
|
instance_eval(&block)
|
14
14
|
end
|
15
15
|
|
16
16
|
def as_jsonapi(included)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
{}.tap do |hash|
|
18
|
+
hash[:links] = @_links if @_links.any?
|
19
|
+
hash[:meta] = @_meta unless @_meta.nil?
|
20
|
+
include_linkage = included || (!@_links.any? && @_meta.nil?)
|
21
|
+
hash[:data] = linkage_data if include_linkage
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def related_resources
|
26
|
+
return @_related_resources if @_related_resources
|
22
27
|
|
23
|
-
|
28
|
+
resources = @_resources_block.call
|
29
|
+
@_arity = resources.respond_to?(:each) ? :many : :one
|
30
|
+
@_related_resources = Array(resources)
|
31
|
+
|
32
|
+
@_related_resources
|
24
33
|
end
|
25
34
|
|
26
35
|
private
|
27
36
|
|
28
37
|
def linkage_data
|
29
|
-
|
38
|
+
return @_linkage_block.call if @_linkage_block
|
39
|
+
|
40
|
+
linkage_data = related_resources.map do |res|
|
30
41
|
{ type: res.jsonapi_type, id: res.jsonapi_id }
|
31
42
|
end
|
32
43
|
|
33
|
-
|
44
|
+
@_arity == :many ? linkage_data : linkage_data.first
|
34
45
|
end
|
35
46
|
end
|
36
47
|
end
|
@@ -3,55 +3,58 @@ require 'jsonapi/serializable/resource_builder'
|
|
3
3
|
module JSONAPI
|
4
4
|
module Serializable
|
5
5
|
module RelationshipDSL
|
6
|
-
# Declare the
|
6
|
+
# Declare the related resources for this relationship.
|
7
7
|
# @param [String,Constant,Hash{Symbol=>String,Constant}] resource_class
|
8
|
-
# @yieldreturn The
|
8
|
+
# @yieldreturn The related resources for this relationship.
|
9
9
|
# If it is nil, an object implementing the Serializable::Resource
|
10
10
|
# interface, an empty array, or an array of objects implementing the
|
11
11
|
# Serializable::Resource interface, then it is used as is.
|
12
|
-
# Otherwise an appropriate Serializable::
|
12
|
+
# Otherwise an appropriate Serializable::Resource subclass is inferred
|
13
13
|
# from the object(s)' namespace/class, the resource_class parameter if
|
14
14
|
# provided, and the @_resource_inferer.
|
15
15
|
#
|
16
16
|
# @example
|
17
|
-
#
|
17
|
+
# resources do
|
18
18
|
# @user.posts.map { |p| PostResource.new(post: p) }
|
19
19
|
# end
|
20
20
|
#
|
21
21
|
# @example
|
22
|
-
#
|
22
|
+
# resources do
|
23
23
|
# @post.author && UserResource.new(user: @user.author)
|
24
24
|
# end
|
25
25
|
#
|
26
26
|
# @example
|
27
|
-
#
|
27
|
+
# resources do
|
28
28
|
# @user.posts
|
29
29
|
# end
|
30
30
|
# end
|
31
31
|
#
|
32
32
|
# @example
|
33
|
-
#
|
33
|
+
# resources SerializablePost do
|
34
34
|
# @user.posts
|
35
35
|
# end
|
36
36
|
#
|
37
37
|
# @example
|
38
|
-
#
|
38
|
+
# resources "SerializableUser" do
|
39
39
|
# @post.author
|
40
40
|
# end
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
_resources_for(yield, resource_class)
|
47
|
-
end
|
48
|
-
else
|
49
|
-
# NOTE(beauby): In the case of a computation heavy relationship with
|
50
|
-
# nil value, this block might be executed multiple times.
|
51
|
-
@_data ||= @_data_block.call
|
41
|
+
def resources(resource_class = nil)
|
42
|
+
# NOTE(beauby): Lazify computation since it is only needed when
|
43
|
+
# the corresponding relationship is included.
|
44
|
+
@_resources_block = proc do
|
45
|
+
_resources_for(yield, resource_class)
|
52
46
|
end
|
53
47
|
end
|
54
48
|
|
49
|
+
# Explicitly declare linkage data.
|
50
|
+
# @yieldreturn The resource linkage.
|
51
|
+
def data(&block)
|
52
|
+
# NOTE(beauby): Lazify computation since it is only executed when
|
53
|
+
# the corresponding relationship is included (or no links and
|
54
|
+
# no meta was specified).
|
55
|
+
@_linkage_block = block
|
56
|
+
end
|
57
|
+
|
55
58
|
# @overload meta(value)
|
56
59
|
# Declare the meta information for this relationship.
|
57
60
|
# @param [Hash] value The meta information hash.
|
@@ -90,16 +93,16 @@ module JSONAPI
|
|
90
93
|
# meta authorization_needed: true
|
91
94
|
# end
|
92
95
|
def link(name, &block)
|
93
|
-
@_links[name] = Link.as_jsonapi(@
|
96
|
+
@_links[name] = Link.as_jsonapi(@_exposures, &block)
|
94
97
|
end
|
95
98
|
|
96
99
|
private
|
97
100
|
|
98
101
|
# @api private
|
99
|
-
def _resources_for(
|
102
|
+
def _resources_for(objects, resource_class)
|
100
103
|
resource_class ||= @_resource_inferer
|
101
104
|
|
102
|
-
ResourceBuilder.build(
|
105
|
+
ResourceBuilder.build(objects, @_exposures, resource_class)
|
103
106
|
end
|
104
107
|
end
|
105
108
|
end
|
@@ -1,14 +1,15 @@
|
|
1
1
|
require 'jsonapi/renderer'
|
2
|
+
require 'jsonapi/serializable/resource_builder'
|
2
3
|
|
3
4
|
module JSONAPI
|
4
5
|
module Serializable
|
5
6
|
class Renderer
|
6
|
-
def self.render(
|
7
|
-
new(
|
7
|
+
def self.render(objects, options)
|
8
|
+
new(objects, options).render
|
8
9
|
end
|
9
10
|
|
10
|
-
def initialize(
|
11
|
-
@
|
11
|
+
def initialize(objects, options)
|
12
|
+
@objects = objects
|
12
13
|
@options = options.dup
|
13
14
|
@klass = @options.delete(:class)
|
14
15
|
@namespace = @options.delete(:namespace)
|
@@ -29,7 +30,7 @@ module JSONAPI
|
|
29
30
|
|
30
31
|
def jsonapi_resources
|
31
32
|
toplevel_inferer = @klass || @inferer
|
32
|
-
JSONAPI::Serializable::ResourceBuilder.build(@
|
33
|
+
JSONAPI::Serializable::ResourceBuilder.build(@objects,
|
33
34
|
@exposures,
|
34
35
|
toplevel_inferer)
|
35
36
|
end
|
@@ -1,106 +1,12 @@
|
|
1
|
-
require 'jsonapi/serializable/
|
2
|
-
require 'jsonapi/serializable/relationship'
|
1
|
+
require 'jsonapi/serializable/abstract_resource'
|
3
2
|
require 'jsonapi/serializable/resource_dsl'
|
4
3
|
|
5
4
|
module JSONAPI
|
6
5
|
module Serializable
|
7
|
-
class Resource
|
6
|
+
class Resource < AbstractResource
|
8
7
|
include ResourceDSL
|
9
8
|
|
10
|
-
|
11
|
-
attr_accessor :type_val, :type_block, :id_block, :attribute_blocks,
|
12
|
-
:relationship_blocks, :link_blocks, :meta_val, :meta_block
|
13
|
-
end
|
14
|
-
|
15
|
-
self.attribute_blocks = {}
|
16
|
-
self.relationship_blocks = {}
|
17
|
-
self.link_blocks = {}
|
18
|
-
|
19
|
-
def self.inherited(klass)
|
20
|
-
super
|
21
|
-
klass.type_val = type_val
|
22
|
-
klass.type_block = type_block
|
23
|
-
klass.id_block = id_block
|
24
|
-
klass.meta_val = meta_val
|
25
|
-
klass.meta_block = meta_block
|
26
|
-
klass.attribute_blocks = attribute_blocks.dup
|
27
|
-
klass.relationship_blocks = relationship_blocks.dup
|
28
|
-
klass.link_blocks = link_blocks.dup
|
29
|
-
end
|
30
|
-
|
31
|
-
def initialize(param_hash = {})
|
32
|
-
@_param_hash = param_hash
|
33
|
-
param_hash.each { |k, v| instance_variable_set("@#{k}", v) }
|
34
|
-
end
|
35
|
-
|
36
|
-
def as_jsonapi(params = {})
|
37
|
-
return nil if nil?
|
38
|
-
|
39
|
-
{}.tap do |hash|
|
40
|
-
hash[:id] = jsonapi_id
|
41
|
-
hash[:type] = jsonapi_type
|
42
|
-
requested_attrs = params[:fields] || self.class.attribute_blocks.keys
|
43
|
-
attrs = attributes(requested_attrs)
|
44
|
-
hash[:attributes] = attrs if attrs.any?
|
45
|
-
requested_rels = params[:fields] ||
|
46
|
-
self.class.relationship_blocks.keys
|
47
|
-
rels = relationships(requested_rels, params[:include] || [])
|
48
|
-
hash[:relationships] = rels if rels.any?
|
49
|
-
hash[:links] = links if links.any?
|
50
|
-
hash[:meta] = meta unless meta.nil?
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def jsonapi_type
|
55
|
-
@_type ||= self.class.type_val || instance_eval(&self.class.type_block)
|
56
|
-
end
|
57
|
-
|
58
|
-
def jsonapi_id
|
59
|
-
@_id ||= instance_eval(&self.class.id_block)
|
60
|
-
end
|
61
|
-
|
62
|
-
def jsonapi_related(include)
|
63
|
-
@_relationships
|
64
|
-
.select { |k, _| include.include?(k) }
|
65
|
-
.each_with_object({}) { |(k, v), h| h[k] = Array(v.data) }
|
66
|
-
end
|
67
|
-
|
68
|
-
private
|
69
|
-
|
70
|
-
def attributes(fields)
|
71
|
-
@_attributes ||= {}
|
72
|
-
self.class.attribute_blocks
|
73
|
-
.select { |k, _| !@_attributes.key?(k) && fields.include?(k) }
|
74
|
-
.each { |k, v| @_attributes[k] = instance_eval(&v) }
|
75
|
-
@_attributes.select { |k, _| fields.include?(k) }
|
76
|
-
end
|
77
|
-
|
78
|
-
def relationships(fields, include)
|
79
|
-
@_relationships ||= self.class.relationship_blocks
|
80
|
-
.each_with_object({}) do |(k, v), h|
|
81
|
-
h[k] = Relationship.new(@_param_hash, &v)
|
82
|
-
end
|
83
|
-
@_relationships
|
84
|
-
.select { |k, _| fields.include?(k) }
|
85
|
-
.each_with_object({}) do |(k, v), h|
|
86
|
-
h[k] = v.as_jsonapi(include.include?(k))
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def meta
|
91
|
-
@_meta ||=
|
92
|
-
if self.class.meta_val
|
93
|
-
self.class.meta_val
|
94
|
-
elsif self.class.meta_block
|
95
|
-
instance_eval(&self.class.meta_block)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def links
|
100
|
-
@_links ||= self.class.link_blocks.each_with_object({}) do |(k, v), h|
|
101
|
-
h[k] = Link.as_jsonapi(@_param_hash, &v)
|
102
|
-
end
|
103
|
-
end
|
9
|
+
id { @object.public_send(:id).to_s }
|
104
10
|
end
|
105
11
|
end
|
106
12
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module JSONAPI
|
2
2
|
module Serializable
|
3
3
|
class ResourceBuilder
|
4
|
-
DEFAULT_RESOURCE_INFERER = lambda do |
|
5
|
-
names =
|
4
|
+
DEFAULT_RESOURCE_INFERER = lambda do |object_klass_name|
|
5
|
+
names = object_klass_name.split('::'.freeze)
|
6
6
|
klass_name = names.pop
|
7
7
|
namespace = names.join('::'.freeze)
|
8
8
|
|
@@ -14,20 +14,21 @@ module JSONAPI
|
|
14
14
|
Object.const_get(klass_name)
|
15
15
|
end
|
16
16
|
|
17
|
-
def self.build(
|
18
|
-
return
|
19
|
-
|
17
|
+
def self.build(objects, expose, klass)
|
18
|
+
return objects if objects.nil? ||
|
19
|
+
Array(objects).first.respond_to?(:as_jsonapi)
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
if objects.respond_to?(:each)
|
22
|
+
objects.map { |obj| new(obj, expose, klass).resource }
|
23
|
+
else
|
24
|
+
new(objects, expose, klass).resource
|
25
|
+
end
|
25
26
|
end
|
26
27
|
|
27
28
|
attr_reader :resource
|
28
29
|
|
29
|
-
def initialize(
|
30
|
-
@
|
30
|
+
def initialize(object, expose, klass)
|
31
|
+
@object = object
|
31
32
|
@expose = expose || {}
|
32
33
|
@klass = klass
|
33
34
|
@resource = serializable_class.new(serializable_params)
|
@@ -37,18 +38,18 @@ module JSONAPI
|
|
37
38
|
private
|
38
39
|
|
39
40
|
def serializable_params
|
40
|
-
@expose.merge(
|
41
|
+
@expose.merge(object: @object)
|
41
42
|
end
|
42
43
|
|
43
44
|
# rubocop:disable Metrics/MethodLength
|
44
45
|
def serializable_class
|
45
46
|
klass =
|
46
47
|
if @klass.respond_to?(:call)
|
47
|
-
@klass.call(@
|
48
|
+
@klass.call(@object.class.name)
|
48
49
|
elsif @klass.is_a?(Hash)
|
49
|
-
@klass[@
|
50
|
+
@klass[@object.class.name.to_sym]
|
50
51
|
elsif @klass.nil?
|
51
|
-
DEFAULT_RESOURCE_INFERER.call(@
|
52
|
+
DEFAULT_RESOURCE_INFERER.call(@object.class.name)
|
52
53
|
else
|
53
54
|
@klass
|
54
55
|
end
|
@@ -6,124 +6,27 @@ module JSONAPI
|
|
6
6
|
end
|
7
7
|
|
8
8
|
module ClassMethods
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
#
|
13
|
-
# @example
|
14
|
-
# type 'users'
|
15
|
-
#
|
16
|
-
# @overload type(value)
|
17
|
-
# Declare the JSON API type of this resource.
|
18
|
-
# @yieldreturn [String] The value of the type.
|
19
|
-
#
|
20
|
-
# @example
|
21
|
-
# type { @user.admin? ? "admin" : "users" }
|
22
|
-
def type(value = nil, &block)
|
23
|
-
self.type_val = value
|
24
|
-
self.type_block = block
|
9
|
+
def attribute(attr, &block)
|
10
|
+
block ||= proc { @object.public_send(attr) }
|
11
|
+
super(attr, &block)
|
25
12
|
end
|
26
13
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
# @example
|
32
|
-
# id { @user.id.to_s }
|
33
|
-
def id(&block)
|
34
|
-
self.id_block = block
|
14
|
+
def attributes(*args)
|
15
|
+
args.each do |attr|
|
16
|
+
attribute(attr)
|
17
|
+
end
|
35
18
|
end
|
36
19
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
#
|
44
|
-
# @overload meta(&block)
|
45
|
-
# Declare the meta information for this resource.
|
46
|
-
# @yieldreturn [String] The meta information hash.
|
47
|
-
# @example
|
48
|
-
# meta do
|
49
|
-
# { key: value }
|
50
|
-
# end
|
51
|
-
def meta(value = nil, &block)
|
52
|
-
self.meta_val = value
|
53
|
-
self.meta_block = block
|
54
|
-
end
|
55
|
-
|
56
|
-
# Declare an attribute for this resource.
|
57
|
-
#
|
58
|
-
# @param [Symbol] name The key of the attribute.
|
59
|
-
# @yieldreturn [Hash, String, nil] The block to compute the value.
|
60
|
-
#
|
61
|
-
# @example
|
62
|
-
# attribute(:name) { @user.name }
|
63
|
-
def attribute(name, &block)
|
64
|
-
attribute_blocks[name] = block
|
65
|
-
end
|
66
|
-
|
67
|
-
# Declare a relationship for this resource. The properties of the
|
68
|
-
# relationship are set by providing a block in which the DSL methods
|
69
|
-
# of +JSONAPI::Serializable::Relationship+ are called.
|
70
|
-
# @see JSONAPI::Serializable::Relationship
|
71
|
-
#
|
72
|
-
# @param [Symbol] name The key of the relationship.
|
73
|
-
#
|
74
|
-
# @example
|
75
|
-
# relationship :posts do
|
76
|
-
# data { @user.posts.map { |p| PostResource.new(post: p) } }
|
77
|
-
# end
|
78
|
-
#
|
79
|
-
# @example
|
80
|
-
# relationship :author do
|
81
|
-
# data do
|
82
|
-
# @post.author && UserResource.new(user: @post.author)
|
83
|
-
# end
|
84
|
-
# linkage_data do
|
85
|
-
# { type: 'users', id: @post.author_id }
|
86
|
-
# end
|
87
|
-
# link(:self) do
|
88
|
-
# "http://api.example.com/posts/#{@post.id}/relationships/author"
|
89
|
-
# end
|
90
|
-
# link(:related) do
|
91
|
-
# "http://api.example.com/posts/#{@post.id}/author"
|
92
|
-
# end
|
93
|
-
# meta do
|
94
|
-
# { author_online: @post.author.online? }
|
95
|
-
# end
|
96
|
-
# end
|
97
|
-
def relationship(name, &block)
|
98
|
-
relationship_blocks[name] = block
|
20
|
+
def relationship(rel, resource_class = nil, &block)
|
21
|
+
rel_block = proc do
|
22
|
+
resources(resource_class) { @object.public_send(rel) }
|
23
|
+
instance_eval(&block) unless block.nil?
|
24
|
+
end
|
25
|
+
super(rel, &rel_block)
|
99
26
|
end
|
100
27
|
alias has_many relationship
|
101
28
|
alias has_one relationship
|
102
29
|
alias belongs_to relationship
|
103
|
-
|
104
|
-
# Declare a link for this resource. The properties of the link are set
|
105
|
-
# by providing a block in which the DSL methods of
|
106
|
-
# +JSONAPI::Serializable::Link+ are called, or the value of the link
|
107
|
-
# is returned directly.
|
108
|
-
# @see JSONAPI::Serialiable::Link
|
109
|
-
#
|
110
|
-
# @param [Symbol] name The key of the link.
|
111
|
-
# @yieldreturn [Hash, String, nil] The block to compute the value, if
|
112
|
-
# any.
|
113
|
-
#
|
114
|
-
# @example
|
115
|
-
# link(:self) do
|
116
|
-
# "http://api.example.com/users/#{@user.id}"
|
117
|
-
# end
|
118
|
-
#
|
119
|
-
# @example
|
120
|
-
# link(:self) do
|
121
|
-
# href "http://api.example.com/users/#{@user.id}"
|
122
|
-
# meta is_self: true
|
123
|
-
# end
|
124
|
-
def link(name, &block)
|
125
|
-
link_blocks[name] = block
|
126
|
-
end
|
127
30
|
end
|
128
31
|
end
|
129
32
|
end
|
data/lib/jsonapi/serializable.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi-serializable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.1.
|
4
|
+
version: 0.1.1.beta4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lucas Hosseini
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jsonapi-renderer
|
@@ -60,11 +60,11 @@ extra_rdoc_files: []
|
|
60
60
|
files:
|
61
61
|
- README.md
|
62
62
|
- lib/jsonapi/serializable.rb
|
63
|
+
- lib/jsonapi/serializable/abstract_resource.rb
|
64
|
+
- lib/jsonapi/serializable/abstract_resource_dsl.rb
|
63
65
|
- lib/jsonapi/serializable/error.rb
|
64
66
|
- lib/jsonapi/serializable/error_dsl.rb
|
65
67
|
- lib/jsonapi/serializable/link.rb
|
66
|
-
- lib/jsonapi/serializable/model.rb
|
67
|
-
- lib/jsonapi/serializable/model_dsl.rb
|
68
68
|
- lib/jsonapi/serializable/relationship.rb
|
69
69
|
- lib/jsonapi/serializable/relationship_dsl.rb
|
70
70
|
- lib/jsonapi/serializable/renderer.rb
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module JSONAPI
|
2
|
-
module Serializable
|
3
|
-
module ModelDSL
|
4
|
-
def self.included(base)
|
5
|
-
base.extend(ClassMethods)
|
6
|
-
end
|
7
|
-
|
8
|
-
module ClassMethods
|
9
|
-
def attribute(attr, &block)
|
10
|
-
block ||= proc { @model.public_send(attr) }
|
11
|
-
super(attr, &block)
|
12
|
-
end
|
13
|
-
|
14
|
-
def relationship(rel, resource_class = nil, &block)
|
15
|
-
rel_block = proc do
|
16
|
-
data(resource_class) { @model.public_send(rel) }
|
17
|
-
instance_eval(&block) unless block.nil?
|
18
|
-
end
|
19
|
-
super(rel, &rel_block)
|
20
|
-
end
|
21
|
-
alias has_many relationship
|
22
|
-
alias has_one relationship
|
23
|
-
alias belongs_to relationship
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|