simple_ams 0.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 +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/README.md +224 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/simple_ams/adapters/ams.rb +85 -0
- data/lib/simple_ams/adapters.rb +2 -0
- data/lib/simple_ams/document/fields.rb +66 -0
- data/lib/simple_ams/document/links.rb +61 -0
- data/lib/simple_ams/document/metas.rb +15 -0
- data/lib/simple_ams/document/relations.rb +95 -0
- data/lib/simple_ams/document.rb +93 -0
- data/lib/simple_ams/dsl.rb +216 -0
- data/lib/simple_ams/methy.rb +10 -0
- data/lib/simple_ams/options/adapter.rb +9 -0
- data/lib/simple_ams/options/concerns/filterable.rb +45 -0
- data/lib/simple_ams/options/concerns/name_value_hash.rb +32 -0
- data/lib/simple_ams/options/concerns/value_hash.rb +23 -0
- data/lib/simple_ams/options/fields.rb +7 -0
- data/lib/simple_ams/options/includes.rb +7 -0
- data/lib/simple_ams/options/links.rb +11 -0
- data/lib/simple_ams/options/metas.rb +12 -0
- data/lib/simple_ams/options/primary_id.rb +7 -0
- data/lib/simple_ams/options/relation.rb +31 -0
- data/lib/simple_ams/options/type.rb +8 -0
- data/lib/simple_ams/options.rb +299 -0
- data/lib/simple_ams/renderer.rb +59 -0
- data/lib/simple_ams/version.rb +3 -0
- data/lib/simple_ams.rb +29 -0
- data/simple_ams.gemspec +29 -0
- metadata +160 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5193c4f1997cfc84c8fdf5fa90abfde7ac2a03a2
|
4
|
+
data.tar.gz: 13c6c665417899d0a73d9900144d58e8f848e370
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b6affb011516c6e9b69b829c176966305b38f7d102b874248bac63fb089c8b84b27cec6190e067364943935b26164bcc066d12ebad77c88d412edaf7db6724aa
|
7
|
+
data.tar.gz: c44a84ff86b1a0d2eb5b67670b508a3cfa6da2ded1cc0353fd0709b73a352a7a2d1bf735860cba76ae03f696e4eefab50c4704b67229be8fb1285f43376c8ea2
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,224 @@
|
|
1
|
+
# SimpleAMS
|
2
|
+
> "Simple things should be simple and complex things should be possible." Alan Kay.
|
3
|
+
|
4
|
+
If we want to interact with modern APIs we should start building modern, flexible libraries
|
5
|
+
that help developers to build such APIs. Modern Ruby serializers, as I always wanted them to be.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'simple_ams'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install simple_ams
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
The gem's interface has been inspired by ActiveModel Serializers 0.9.2, 0.10.stable, jsonapi-rb and Ember Data.
|
25
|
+
However, **it has been built for POROs, does not rely in any dependency and does not relate to Rails in any case** other than
|
26
|
+
some nostalgia for the (advanced at that time) pre-0.10 ActiveModel Serialiers.
|
27
|
+
|
28
|
+
|
29
|
+
### Simple case
|
30
|
+
|
31
|
+
You will rarely need all the advanced options. Usually you will have something like that:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
class UserSerializer
|
35
|
+
include SimpleAMS::DSL
|
36
|
+
|
37
|
+
#specify the adapter, pass some options all the way down to the adapter
|
38
|
+
adapter SimpleAMS::Adapters::JSONAPI, root: true
|
39
|
+
|
40
|
+
#specify available attributes/fields
|
41
|
+
attributes :id, :name, :email, :birth_date
|
42
|
+
|
43
|
+
#specify available relations
|
44
|
+
has_many :videos, :comments, :posts
|
45
|
+
belongs_to :organization
|
46
|
+
has_one :profile
|
47
|
+
|
48
|
+
#specify some links
|
49
|
+
link :feed, '/api/v1/me/feed'
|
50
|
+
#links can also take other options, as specified by RFC 8288
|
51
|
+
link :root, '/api/v1/', rel: :user
|
52
|
+
#link values can be dynamic as well through lambdas
|
53
|
+
link :posts, ->(obj) { "/api/v1/users/#{obj.id}/posts/" }, rel: :user
|
54
|
+
#if you also need dynamic options, you can return an array from the lambda
|
55
|
+
link :followers, ->(obj) { ["/api/v1/users/#{obj.id}/followers/", rel: obj.type] }
|
56
|
+
|
57
|
+
#same with metas: can be static, dynamic and accept arbitrary options
|
58
|
+
meta :environment, ->(obj) { Rails.env.to_s }
|
59
|
+
|
60
|
+
#collection accepts exactly the same aforementioned interface
|
61
|
+
#although you will rarely use it to full extend
|
62
|
+
#here we use only links and meta
|
63
|
+
collection do
|
64
|
+
link :root, '/api/v1/', rel: :user
|
65
|
+
type :users
|
66
|
+
meta :count, ->(collection) { collection.count }
|
67
|
+
end
|
68
|
+
|
69
|
+
#note that there is a shortcut if you just need to specify the collection name/type:
|
70
|
+
#collection :users
|
71
|
+
|
72
|
+
#override an attribute
|
73
|
+
def name
|
74
|
+
"#{object.first_name} #{object.last_name}"
|
75
|
+
end
|
76
|
+
|
77
|
+
#override a relation
|
78
|
+
def videos
|
79
|
+
Videos.where(user_id: object.id).published
|
80
|
+
end
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
Then you can just feed your serializer with data, along with some options:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
SimpleAMS::Renderer.new(user, fields: [:id, :name, :email], includes: [:videos]).to_json
|
88
|
+
```
|
89
|
+
`to_json` first calls `as_json`, which creates a ruby Hash and then `to_json` is called
|
90
|
+
on top of that hash.
|
91
|
+
|
92
|
+
|
93
|
+
# Advanced usage
|
94
|
+
The DSL in the previous example is just syntactic sugar. In the basis, there is a very powerful
|
95
|
+
hash-based DSL that can be used in 3 different places:
|
96
|
+
|
97
|
+
* When initializing the `SimpleAMS::Renderer` class to render the data using specific serializer, adapter and options.
|
98
|
+
* Inside a class that has the `SimpleAMS::DSL` included, using the `with_options({})` class method
|
99
|
+
* Through the DSL, powered with some syntactic sugar
|
100
|
+
|
101
|
+
In any case, we have the following options:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
{
|
105
|
+
#the primary id of the record(s), used mostly by the underlying adapter (like JSONAPI)
|
106
|
+
primary_id: :id,
|
107
|
+
#the type of the record, used mostly by the underlying adapter (like JSONAPI)
|
108
|
+
type: :user,
|
109
|
+
#which relations should be included
|
110
|
+
includes: [:posts, videos: [:comments]],
|
111
|
+
#which fields for each relation should be included
|
112
|
+
fields: [:id, :name, posts: [:id, :text], videos: [:id, :title, comments: [:id, :text]]] #overrides includes when association is specified
|
113
|
+
relations: [
|
114
|
+
[:belongs_to, :company, {
|
115
|
+
serializer: CompanySerializer,
|
116
|
+
fields: Company.column_names.map(&:to_sym)
|
117
|
+
}
|
118
|
+
],
|
119
|
+
[:has_many, :followers, {
|
120
|
+
serializer: UserSerializer,
|
121
|
+
fields: User.column_names.map(&:to_sym)
|
122
|
+
],
|
123
|
+
]
|
124
|
+
#the serializer that should be used
|
125
|
+
#makes sense to use it when initializing the Renderer
|
126
|
+
serializer: UserSerializer,
|
127
|
+
#can also be a lambda, in case of polymorphic records, ideal for ArrayRenderer
|
128
|
+
serializer: ->(obj){ obj.employee? ? EmployeeSerializer : UserSerializer }
|
129
|
+
#specifying the underlying adapter. This cannot be a lambda in case of ArrayRenderer,
|
130
|
+
#but can take some useful options that are passed down straight to the adapter class.
|
131
|
+
adapter: SimpleAMS::Adapters::AMS, root: true
|
132
|
+
#the links data
|
133
|
+
links: {
|
134
|
+
#can be a simple string
|
135
|
+
root: '/api/v1'
|
136
|
+
#a string with some options (relation and target attributes as defined by RFC8288
|
137
|
+
#however, you can also pass adapter-specific attributes
|
138
|
+
posts: "/api/v1/posts/", rel: :posts,
|
139
|
+
#it can also be a lambda that takes the resource to be rendered as a param
|
140
|
+
#when the lambda is called, it should return the array structure above
|
141
|
+
self: ->(obj) { ["/api/v1/users/#{obj.id}", rel: :user] }
|
142
|
+
},
|
143
|
+
#the meta data, same as the links data (available in adapters even for single records)
|
144
|
+
metas: {
|
145
|
+
type: ->(obj){ obj.employee? ? :employee : :user}
|
146
|
+
#meta can take arbitrary options as well
|
147
|
+
authorization: :oauth, type: :bearer_token
|
148
|
+
},
|
149
|
+
#collection parameters, used only in ArrayRenderer
|
150
|
+
collection: {
|
151
|
+
links: {
|
152
|
+
root: '/api/v1'
|
153
|
+
},
|
154
|
+
metas: {
|
155
|
+
pages: ->(obj) { [obj.pages, collection: true]},
|
156
|
+
current_page: ->(obj) { [obj.current_page, collection: true] },
|
157
|
+
previous_page: ->(obj) { [obj.previous_page, collection: true] },
|
158
|
+
next_page: ->(obj) { [obj.next_page, collection: true] },
|
159
|
+
max_per_page: 50,
|
160
|
+
},
|
161
|
+
}
|
162
|
+
#exposing helpers that will be available inside the seriralizer
|
163
|
+
expose: {
|
164
|
+
#a class
|
165
|
+
current_user: User.first
|
166
|
+
#or a module
|
167
|
+
helpers: CommonHelpers
|
168
|
+
},
|
169
|
+
}
|
170
|
+
```
|
171
|
+
|
172
|
+
Now let those options be `OPTIONS`. These can be fed to either the `SimpleAMS::Renderer`
|
173
|
+
or to the serializer class itself using the `with_options` class method. Let's see how:
|
174
|
+
|
175
|
+
```ruby
|
176
|
+
class UserSerializer
|
177
|
+
include SimpleAMS::DSL
|
178
|
+
|
179
|
+
with_options({ #you can pass the same options as above ;)
|
180
|
+
primary_id: :id,
|
181
|
+
# ...
|
182
|
+
# ...
|
183
|
+
# ...
|
184
|
+
})
|
185
|
+
|
186
|
+
def name
|
187
|
+
"#{object.first_name} #{object.last_name}"
|
188
|
+
end
|
189
|
+
|
190
|
+
def videos
|
191
|
+
Videos.where(user_id: object.id).published
|
192
|
+
end
|
193
|
+
end
|
194
|
+
```
|
195
|
+
|
196
|
+
The same options can be passed when calling the `Renderer`. `Renderer` can override
|
197
|
+
some properties, however in all properties that act as sets/arrays (like
|
198
|
+
attributes/fields, includes, links etc.), **specified serializer options take precedence** over
|
199
|
+
`Renderer` options.
|
200
|
+
|
201
|
+
```ruby
|
202
|
+
SimpleAMS::Renderer.new(user, {
|
203
|
+
primary_id: :id,
|
204
|
+
serializer: UserSerializer,
|
205
|
+
# ...
|
206
|
+
# ...
|
207
|
+
# ...
|
208
|
+
}).to_json
|
209
|
+
|
210
|
+
```
|
211
|
+
## Development
|
212
|
+
|
213
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
214
|
+
|
215
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
216
|
+
|
217
|
+
## Contributing
|
218
|
+
But reports are very welcome at https://github.com/vasilakisfil/SimpleAMS. Please add as much info as you can (serializer and Renderer input)
|
219
|
+
so that we can easily track down the bug.
|
220
|
+
|
221
|
+
Pull requests are also very welcome on GitHub at https://github.com/vasilakisfil/SimpleAMS.
|
222
|
+
However, to keep the code's sanity (AMS I am looking to you), **I will be very picky** on the code style and design,
|
223
|
+
to match (my) existing code characteristics.
|
224
|
+
Because at the end of the day, it's gonna be me who will maintain this thing.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "SimpleAMS"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require "simple_ams"
|
2
|
+
|
3
|
+
class SimpleAMS::Adapters::AMS
|
4
|
+
attr_reader :document, :options
|
5
|
+
|
6
|
+
def initialize(document, options = {})
|
7
|
+
@document = document
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def as_json
|
12
|
+
hash = {}
|
13
|
+
|
14
|
+
#TODO: I think bang method for merging is way faster ?
|
15
|
+
hash = hash.merge(fields)
|
16
|
+
hash = hash.merge(relations)
|
17
|
+
hash = hash.merge(links: links) unless links.empty?
|
18
|
+
hash = hash.merge(metas: metas) unless metas.empty?
|
19
|
+
|
20
|
+
return hash
|
21
|
+
end
|
22
|
+
|
23
|
+
def fields
|
24
|
+
@fields ||= document.fields.inject({}){ |hash, field|
|
25
|
+
_value = field.value
|
26
|
+
hash[field.key] = _value.respond_to?(:as_json) ? _value.as_json : _value
|
27
|
+
hash
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def links
|
32
|
+
@links ||= document.links.inject({}){ |hash, link|
|
33
|
+
_value = link.value
|
34
|
+
hash[link.name] = _value.respond_to?(:as_json) ? _value.as_json : _value
|
35
|
+
hash
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def metas
|
40
|
+
@metas ||= document.metas.inject({}){ |hash, meta|
|
41
|
+
_value = meta.value
|
42
|
+
hash[meta.name] = _value.respond_to?(:as_json) ? _value.as_json : _value
|
43
|
+
hash
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def relations
|
48
|
+
return {} if document.relations.empty?
|
49
|
+
|
50
|
+
@relations ||= document.relations.inject({}){ |hash, relation|
|
51
|
+
if relation.folder?
|
52
|
+
value = relation.documents.map{|doc| self.class.new(doc).as_json}
|
53
|
+
else
|
54
|
+
value = self.class.new(relation).as_json
|
55
|
+
end
|
56
|
+
hash[relation.name] = value
|
57
|
+
|
58
|
+
hash
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
class Collection < self
|
63
|
+
attr_reader :folder, :adapter, :options
|
64
|
+
|
65
|
+
def initialize(folder, options = {})
|
66
|
+
@folder = folder
|
67
|
+
@adapter = folder.adapter.value
|
68
|
+
@options = options
|
69
|
+
end
|
70
|
+
|
71
|
+
def as_json
|
72
|
+
if options[:root]
|
73
|
+
{folder.name => documents}
|
74
|
+
else
|
75
|
+
documents
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def documents
|
80
|
+
return folder.documents.map{|document|
|
81
|
+
adapter.new(document).as_json
|
82
|
+
} || []
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require "simple_ams"
|
2
|
+
|
3
|
+
module SimpleAMS
|
4
|
+
class Document::Fields
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
attr_reader :members
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
@options = options
|
11
|
+
@members = options.fields #[:field1, :field2]
|
12
|
+
end
|
13
|
+
|
14
|
+
def [](key)
|
15
|
+
found = members.find{|field| field == key}
|
16
|
+
return nil unless found
|
17
|
+
|
18
|
+
return with_decorator(found)
|
19
|
+
end
|
20
|
+
|
21
|
+
def each(&block)
|
22
|
+
return enum_for(:each) unless block_given?
|
23
|
+
|
24
|
+
members.each{ |key|
|
25
|
+
yield with_decorator(key)
|
26
|
+
}
|
27
|
+
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
attr_reader :options
|
33
|
+
|
34
|
+
def with_decorator(key)
|
35
|
+
Field.new(
|
36
|
+
options.resource,
|
37
|
+
options.serializer,
|
38
|
+
key,
|
39
|
+
options
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
class Field
|
44
|
+
attr_reader :key
|
45
|
+
|
46
|
+
#do we need to inject the whole options object?
|
47
|
+
def initialize(resource, serializer, key, options)
|
48
|
+
@resource = resource
|
49
|
+
@serializer = serializer
|
50
|
+
@key = key
|
51
|
+
@options = options
|
52
|
+
end
|
53
|
+
|
54
|
+
def value
|
55
|
+
return @value if defined?(@value)
|
56
|
+
|
57
|
+
return @value = serializer.send(key) if serializer.respond_to? key
|
58
|
+
binding.pry if resource.is_a?(Array)
|
59
|
+
return resource.send(key)
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
attr_reader :resource, :serializer
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "simple_ams"
|
2
|
+
|
3
|
+
module SimpleAMS
|
4
|
+
class Document::Links
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
attr_reader :members
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
@options = options
|
11
|
+
@members = options.links
|
12
|
+
end
|
13
|
+
|
14
|
+
def [](key)
|
15
|
+
found = members.find{|link| link.name == key}
|
16
|
+
return nil unless found
|
17
|
+
|
18
|
+
return with_decorator(found)
|
19
|
+
end
|
20
|
+
|
21
|
+
def each(&block)
|
22
|
+
return enum_for(:each) unless block_given?
|
23
|
+
|
24
|
+
members.each{ |member|
|
25
|
+
yield with_decorator(member)
|
26
|
+
}
|
27
|
+
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
attr_reader :options
|
33
|
+
|
34
|
+
def with_decorator(link)
|
35
|
+
Link.new(link)
|
36
|
+
end
|
37
|
+
|
38
|
+
#memoization maybe ?
|
39
|
+
class Link
|
40
|
+
def initialize(link)
|
41
|
+
@link = link
|
42
|
+
end
|
43
|
+
|
44
|
+
def name
|
45
|
+
link.name
|
46
|
+
end
|
47
|
+
|
48
|
+
def value
|
49
|
+
link.respond_to?(:call) ? link.value.call : link.value
|
50
|
+
end
|
51
|
+
|
52
|
+
def options
|
53
|
+
link.options
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
attr_reader :link
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require "simple_ams"
|
2
|
+
|
3
|
+
#TODO: Add memoization for the relations object (iteration + access)
|
4
|
+
module SimpleAMS
|
5
|
+
class Document::Relations
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
@options = options
|
10
|
+
@relations = options.relations
|
11
|
+
@serializer = options.serializer
|
12
|
+
@resource = options.resource
|
13
|
+
end
|
14
|
+
|
15
|
+
def [](key)
|
16
|
+
found = relations.find{|relation| relation.name == key}
|
17
|
+
return nil unless found
|
18
|
+
|
19
|
+
return relation_for(found)
|
20
|
+
end
|
21
|
+
|
22
|
+
def each(&block)
|
23
|
+
return enum_for(:each) unless block_given?
|
24
|
+
|
25
|
+
relations.each{ |relation|
|
26
|
+
yield relation_for(relation)
|
27
|
+
}
|
28
|
+
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def empty?
|
33
|
+
count == 0
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
attr_reader :options, :relations, :serializer, :resource
|
38
|
+
|
39
|
+
def relation_for(relation)
|
40
|
+
renderer_klass_for(relation).new(
|
41
|
+
SimpleAMS::Options.new(
|
42
|
+
relation_value_for(relation.name), relation_options_for(relation)
|
43
|
+
)
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
#TODO: rename that to relation and existing relation to relationship
|
48
|
+
def relation_value_for(name)
|
49
|
+
if serializer.respond_to?(name)
|
50
|
+
serializer.send(name)
|
51
|
+
else
|
52
|
+
resource.send(name)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
#4 options are merged:
|
57
|
+
# *user injected when instantiating the SimpleAMS class
|
58
|
+
# *relation options injected from parent serializer
|
59
|
+
# *serializer class options
|
60
|
+
def relation_options_for(relation)
|
61
|
+
_relation_options = {
|
62
|
+
injected_options: (relation.options || {}).merge(
|
63
|
+
options.relation_options_for(
|
64
|
+
relation.name
|
65
|
+
).merge(
|
66
|
+
expose: options.expose
|
67
|
+
)
|
68
|
+
).merge(
|
69
|
+
_internal: {
|
70
|
+
module: serializer.class.to_s.rpartition('::').first
|
71
|
+
}
|
72
|
+
)
|
73
|
+
}
|
74
|
+
#TODO: deep merge, can we automate this somehow ?
|
75
|
+
_relation_options[:injected_options][:collection] = (_relation_options[:collection] || {}).merge(
|
76
|
+
name: relation.name
|
77
|
+
)
|
78
|
+
|
79
|
+
return _relation_options
|
80
|
+
end
|
81
|
+
|
82
|
+
def renderer_klass_for(relation)
|
83
|
+
renderer = SimpleAMS::Document
|
84
|
+
collection_renderer = renderer::Folder
|
85
|
+
|
86
|
+
relation.collection? ? collection_renderer : renderer
|
87
|
+
end
|
88
|
+
|
89
|
+
=begin TODO: Add that as public method, should help performance in edge cases
|
90
|
+
def relationship_info_for(name)
|
91
|
+
relations.find{|i| i.name == name}
|
92
|
+
end
|
93
|
+
=end
|
94
|
+
end
|
95
|
+
end
|