cm-active_model_serializers 0.10.0.rc1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.travis.yml +26 -0
  4. data/CHANGELOG.md +8 -0
  5. data/CONTRIBUTING.md +31 -0
  6. data/Gemfile +17 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +326 -0
  9. data/Rakefile +12 -0
  10. data/cm-active_model_serializers.gemspec +26 -0
  11. data/lib/action_controller/serialization.rb +62 -0
  12. data/lib/active_model/serializer.rb +261 -0
  13. data/lib/active_model/serializer/adapter.rb +87 -0
  14. data/lib/active_model/serializer/adapter/fragment_cache.rb +78 -0
  15. data/lib/active_model/serializer/adapter/json.rb +52 -0
  16. data/lib/active_model/serializer/adapter/json/fragment_cache.rb +15 -0
  17. data/lib/active_model/serializer/adapter/json_api.rb +152 -0
  18. data/lib/active_model/serializer/adapter/json_api/fragment_cache.rb +22 -0
  19. data/lib/active_model/serializer/adapter/null.rb +11 -0
  20. data/lib/active_model/serializer/array_serializer.rb +32 -0
  21. data/lib/active_model/serializer/configuration.rb +13 -0
  22. data/lib/active_model/serializer/fieldset.rb +40 -0
  23. data/lib/active_model/serializer/version.rb +5 -0
  24. data/lib/active_model_serializers.rb +18 -0
  25. data/lib/generators/serializer/USAGE +6 -0
  26. data/lib/generators/serializer/serializer_generator.rb +37 -0
  27. data/lib/generators/serializer/templates/serializer.rb +8 -0
  28. data/test/action_controller/adapter_selector_test.rb +51 -0
  29. data/test/action_controller/explicit_serializer_test.rb +110 -0
  30. data/test/action_controller/json_api_linked_test.rb +173 -0
  31. data/test/action_controller/serialization_scope_name_test.rb +63 -0
  32. data/test/action_controller/serialization_test.rb +365 -0
  33. data/test/adapter/fragment_cache_test.rb +27 -0
  34. data/test/adapter/json/belongs_to_test.rb +48 -0
  35. data/test/adapter/json/collection_test.rb +73 -0
  36. data/test/adapter/json/has_many_test.rb +36 -0
  37. data/test/adapter/json_api/belongs_to_test.rb +147 -0
  38. data/test/adapter/json_api/collection_test.rb +89 -0
  39. data/test/adapter/json_api/has_many_embed_ids_test.rb +45 -0
  40. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +98 -0
  41. data/test/adapter/json_api/has_many_test.rb +106 -0
  42. data/test/adapter/json_api/has_one_test.rb +59 -0
  43. data/test/adapter/json_api/linked_test.rb +257 -0
  44. data/test/adapter/json_test.rb +34 -0
  45. data/test/adapter/null_test.rb +25 -0
  46. data/test/adapter_test.rb +43 -0
  47. data/test/array_serializer_test.rb +43 -0
  48. data/test/fixtures/poro.rb +213 -0
  49. data/test/serializers/adapter_for_test.rb +50 -0
  50. data/test/serializers/associations_test.rb +127 -0
  51. data/test/serializers/attribute_test.rb +38 -0
  52. data/test/serializers/attributes_test.rb +63 -0
  53. data/test/serializers/cache_test.rb +128 -0
  54. data/test/serializers/configuration_test.rb +15 -0
  55. data/test/serializers/fieldset_test.rb +26 -0
  56. data/test/serializers/generators_test.rb +59 -0
  57. data/test/serializers/meta_test.rb +78 -0
  58. data/test/serializers/options_test.rb +21 -0
  59. data/test/serializers/serializer_for_test.rb +65 -0
  60. data/test/serializers/urls_test.rb +26 -0
  61. data/test/test_helper.rb +38 -0
  62. metadata +195 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b559963313450922c029f49659dd7d7fa37945cf
4
+ data.tar.gz: 3f5fe0fb9e95ecbb23127b04a6024116f70c5ffd
5
+ SHA512:
6
+ metadata.gz: 984f98b710c921dbd27fbe31a16c28be9550ff8951fa74cf144a7872cf969502d88c1f999468fa7f155eda66d394334548050cf85e0610a1a83ec2b3bac63fca
7
+ data.tar.gz: 63f008efa5e7608782b67c664329bf9a1da10d292a41fb0a617303eabfbc056afb019078640beb069c2070d10fdf6314830549cacad94b332864fa8ab3574f74
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ Vagrantfile
14
+ .vagrant
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
20
+ *.swp
21
+ .ruby-version
@@ -0,0 +1,26 @@
1
+ language: ruby
2
+
3
+ sudo: false
4
+
5
+ rvm:
6
+ - 1.9.3
7
+ - 2.0.0
8
+ - 2.1
9
+ - 2.2
10
+ - jruby-19mode
11
+ - rbx-2
12
+ - ruby-head
13
+
14
+ install:
15
+ - bundle install --retry=3
16
+
17
+ env:
18
+ - "RAILS_VERSION=4.0"
19
+ - "RAILS_VERSION=4.1"
20
+ - "RAILS_VERSION=4.2"
21
+ - "RAILS_VERSION=master"
22
+
23
+ matrix:
24
+ allow_failures:
25
+ - rvm: ruby-head
26
+ - env: "RAILS_VERSION=master"
@@ -0,0 +1,8 @@
1
+ ### 0.10.0
2
+
3
+ * adds support for `meta` and `meta_key` [@kurko]
4
+ * adds method to override association [adcb99e, @kurko]
5
+ * adds `has_one` attribute for backwards compatibility [@ggordon]
6
+ * updates JSON API support to RC3 [@mateomurphy]
7
+ * adds fragment cache support [@joaomdmoura]
8
+ * adds cache support to attributes and associations [@joaomdmoura]
@@ -0,0 +1,31 @@
1
+ ## How can I help?
2
+
3
+ Everyone is encouraged to open issues that are affecting you: bugs, ideas, performance problems – everything helps!
4
+
5
+ The first place to start is by looking at our [GitHub Issues](https://github.com/rails-api/active_model_serializers/issues).
6
+
7
+ The vast majority of development is happening under the `master` branch, currently slated for release as `0.10.x`. This is where we would suggest you start.
8
+
9
+ Fixing bugs is extraordinarily helpful and requires the least familiarity with AMS. Look for issues labeled [**Needs Bug Verification**](https://github.com/rails-api/active_model_serializers/labels/Needs%20Bug%20Verification) and [**Bug**](https://github.com/rails-api/active_model_serializers/labels/bug).
10
+
11
+ We are also actively working to identify tasks under the label [**Good for New Contributors**](https://github.com/rails-api/active_model_serializers/labels/Good%20for%20New%20Contributors). Some bugs are expressly not good for new contributors, so don't expect 100% overlap between the two.
12
+
13
+ If you want to work on new feature development, look for the label [**Feature**](https://github.com/rails-api/active_model_serializers/labels/Feature).
14
+
15
+ We are also encouraging comments to substantial changes (larger than bugfixes and simple features) under an "RFC" (Request for Comments) process before we start active development. Look for the [**RFC**](https://github.com/rails-api/active_model_serializers/labels/RFC) label.
16
+
17
+ ## Issue Labeling
18
+
19
+ AMS uses a subset of [StandardIssueLabels](https://github.com/wagenet/StandardIssueLabels) for Github Issues. You can [see our labels here](https://github.com/rails-api/active_model_serializers/labels).
20
+
21
+ ## Contributing
22
+
23
+ 1. Fork it ( https://github.com/rails-api/active_model_serializers/fork )
24
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
25
+ 3. Write tests for your feature, or regression tests highlighting a bug
26
+ 4. Write the feature itself, or fix your bug
27
+ 5. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 6. Push to the branch (`git push origin my-new-feature`)
29
+ 7. Create a new Pull Request
30
+
31
+ Remember to squash your commits and rebase off `master`.
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in active_model_serializers.gemspec
4
+ gemspec
5
+
6
+ gem "minitest"
7
+
8
+ version = ENV["RAILS_VERSION"] || "4.2"
9
+
10
+ if version == "master"
11
+ gem "rails", github: "rails/rails"
12
+
13
+ # ugh https://github.com/rails/rails/issues/16063#issuecomment-48090125
14
+ gem "arel", github: "rails/arel"
15
+ else
16
+ gem "rails", "~> #{version}.0"
17
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Steve Klabnik
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,326 @@
1
+ # ActiveModel::Serializers
2
+
3
+ [![Build Status](https://travis-ci.org/rails-api/active_model_serializers.svg)](https://travis-ci.org/rails-api/active_model_serializers)
4
+
5
+ ActiveModel::Serializers brings convention over configuration to your JSON generation.
6
+
7
+ AMS does this through two components: **serializers** and **adapters**.
8
+ Serializers describe _which_ attributes and relationships should be serialized.
9
+ Adapters describe _how_ attributes and relationships should be serialized.
10
+
11
+ # RELEASE CANDIDATE, PLEASE READ
12
+
13
+ This is the master branch of AMS. It will become the `0.10.0` release when it's
14
+ ready. Currently this is a release candidate. This is **not** backward
15
+ compatible with `0.9.0` or `0.8.0`.
16
+
17
+ `0.10.x` will be based on the `0.8.0` code, but with a more flexible
18
+ architecture. We'd love your help. [Learn how you can help here.](https://github.com/rails-api/active_model_serializers/blob/master/CONTRIBUTING.md)
19
+
20
+ ## Example
21
+
22
+ Given two models, a `Post(title: string, body: text)` and a
23
+ `Comment(name:string, body:text, post_id:integer)`, you will have two
24
+ serializers:
25
+
26
+ ```ruby
27
+ class PostSerializer < ActiveModel::Serializer
28
+ cache key: 'posts', expires_in: 3.hours
29
+ attributes :title, :body
30
+
31
+ has_many :comments
32
+
33
+ url :post
34
+ end
35
+ ```
36
+
37
+ and
38
+
39
+ ```ruby
40
+ class CommentSerializer < ActiveModel::Serializer
41
+ attributes :name, :body
42
+
43
+ belongs_to :post
44
+
45
+ url [:post, :comment]
46
+ end
47
+ ```
48
+
49
+ Generally speaking, you as a user of AMS will write (or generate) these
50
+ serializer classes. If you want to use a different adapter, such as a JsonApi, you can
51
+ change this in an initializer:
52
+
53
+ ```ruby
54
+ ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::JsonApi
55
+ ```
56
+
57
+ or
58
+
59
+ ```ruby
60
+ ActiveModel::Serializer.config.adapter = :json_api
61
+ ```
62
+
63
+ You won't need to implement an adapter unless you wish to use a new format or
64
+ media type with AMS.
65
+
66
+ If you would like the key in the outputted JSON to be different from its name in ActiveRecord, you can use the :key option to customize it:
67
+
68
+ ```ruby
69
+ class PostSerializer < ActiveModel::Serializer
70
+ attributes :id, :body
71
+
72
+ # look up :subject on the model, but use +title+ in the JSON
73
+ attribute :subject, :key => :title
74
+ has_many :comments
75
+ end
76
+ ```
77
+
78
+ In your controllers, when you use `render :json`, Rails will now first search
79
+ for a serializer for the object and use it if available.
80
+
81
+ ```ruby
82
+ class PostsController < ApplicationController
83
+ def show
84
+ @post = Post.find(params[:id])
85
+
86
+ render json: @post
87
+ end
88
+ end
89
+ ```
90
+
91
+ In this case, Rails will look for a serializer named `PostSerializer`, and if
92
+ it exists, use it to serialize the `Post`.
93
+
94
+ ### Specify a serializer
95
+
96
+ If you wish to use a serializer other than the default, you can explicitly pass it to the renderer.
97
+
98
+ #### 1. For a resource:
99
+
100
+ ```ruby
101
+ render json: @post, serializer: PostPreviewSerializer
102
+ ```
103
+
104
+ #### 2. For an array resource:
105
+
106
+ ```ruby
107
+ # Use the default `ArraySerializer`, which will use `each_serializer` to
108
+ # serialize each element
109
+ render json: @posts, each_serializer: PostPreviewSerializer
110
+
111
+ # Or, you can explicitly provide the collection serializer as well
112
+ render json: @posts, serializer: PaginatedSerializer, each_serializer: PostPreviewSerializer
113
+ ```
114
+
115
+ ### Meta
116
+
117
+ If you want a `meta` attribute in your response, specify it in the `render`
118
+ call:
119
+
120
+ ```ruby
121
+ render json: @post, meta: { total: 10 }
122
+ ```
123
+
124
+ The key can be customized using `meta_key` option.
125
+
126
+ ```ruby
127
+ render json: @post, meta: { total: 10 }, meta_key: "custom_meta"
128
+ ```
129
+
130
+ `meta` will only be included in your response if there's a root. For instance,
131
+ it won't be included in array responses.
132
+
133
+ ### Root key
134
+
135
+ If you want to define a custom root for your response, specify it in the `render`
136
+ call:
137
+
138
+ ```ruby
139
+ render json: @post, root: "articles"
140
+ ```
141
+
142
+ ### Overriding association methods
143
+
144
+ If you want to override any association, you can use:
145
+
146
+ ```ruby
147
+ class PostSerializer < ActiveModel::Serializer
148
+ attributes :id, :body
149
+
150
+ has_many :comments
151
+
152
+ def comments
153
+ object.comments.active
154
+ end
155
+ end
156
+ ```
157
+
158
+ ### Overriding attribute methods
159
+
160
+ If you want to override any attribute, you can use:
161
+
162
+ ```ruby
163
+ class PostSerializer < ActiveModel::Serializer
164
+ attributes :id, :body
165
+
166
+ has_many :comments
167
+
168
+ def body
169
+ object.body.downcase
170
+ end
171
+ end
172
+ ```
173
+
174
+ ### Built in Adapters
175
+
176
+ #### JSONAPI
177
+
178
+ This adapter follows RC3 of the format specified in
179
+ [jsonapi.org/format](http://jsonapi.org/format). It will include the associated
180
+ resources in the `"included"` member when the resource names are included in the
181
+ `include` option.
182
+
183
+ ```ruby
184
+ render @posts, include: ['authors', 'comments']
185
+ # or
186
+ render @posts, include: 'authors,comments'
187
+ ```
188
+
189
+ ## Installation
190
+
191
+ Add this line to your application's Gemfile:
192
+
193
+ ```
194
+ gem 'active_model_serializers'
195
+ ```
196
+
197
+ And then execute:
198
+
199
+ ```
200
+ $ bundle
201
+ ```
202
+
203
+ ## Creating a Serializer
204
+
205
+ The easiest way to create a new serializer is to generate a new resource, which
206
+ will generate a serializer at the same time:
207
+
208
+ ```
209
+ $ rails g resource post title:string body:string
210
+ ```
211
+
212
+ This will generate a serializer in `app/serializers/post_serializer.rb` for
213
+ your new model. You can also generate a serializer for an existing model with
214
+ the serializer generator:
215
+
216
+ ```
217
+ $ rails g serializer post
218
+ ```
219
+
220
+ The generated seralizer will contain basic `attributes` and
221
+ `has_many`/`has_one`/`belongs_to` declarations, based on the model. For example:
222
+
223
+ ```ruby
224
+ class PostSerializer < ActiveModel::Serializer
225
+ attributes :title, :body
226
+
227
+ has_many :comments
228
+ has_one :author
229
+
230
+ url :post
231
+ end
232
+ ```
233
+
234
+ and
235
+
236
+ ```ruby
237
+ class CommentSerializer < ActiveModel::Serializer
238
+ attributes :name, :body
239
+
240
+ belongs_to :post_id
241
+
242
+ url [:post, :comment]
243
+ end
244
+ ```
245
+
246
+ The attribute names are a **whitelist** of attributes to be serialized.
247
+
248
+ The `has_many`, `has_one`, and `belongs_to` declarations describe relationships between
249
+ resources. By default, when you serialize a `Post`, you will get its `Comment`s
250
+ as well.
251
+
252
+ You may also use the `:serializer` option to specify a custom serializer class, for example:
253
+
254
+ ```ruby
255
+ has_many :comments, serializer: CommentPreviewSerializer
256
+ ```
257
+
258
+ The `url` declaration describes which named routes to use while generating URLs
259
+ for your JSON. Not every adapter will require URLs.
260
+
261
+ ## Caching
262
+
263
+ To cache a serializer, call ```cache``` and pass its options.
264
+ The options are the same options of ```ActiveSupport::Cache::Store```, plus
265
+ a ```key``` option that will be the prefix of the object cache
266
+ on a pattern ```"#{key}/#{object.id}-#{object.updated_at}"```.
267
+
268
+ The cache support is optimized to use the cached object in multiple request. An object cached on a ```show``` request will be reused at the ```index```. If there is a relationship with another cached serializer it will also be created and reused automatically.
269
+
270
+ **[NOTE] Every object is individually cached.**
271
+
272
+ **[NOTE] The cache is automatically expired after update an object but it's not deleted.**
273
+
274
+ ```ruby
275
+ cache(options = nil) # options: ```{key, expires_in, compress, force, race_condition_ttl}```
276
+ ```
277
+
278
+ Take the example bellow:
279
+
280
+ ```ruby
281
+ class PostSerializer < ActiveModel::Serializer
282
+ cache key: 'post', expires_in: 3.hours
283
+ attributes :title, :body
284
+
285
+ has_many :comments
286
+
287
+ url :post
288
+ end
289
+ ```
290
+
291
+ On this example every ```Post``` object will be cached with
292
+ the key ```"post/#{post.id}-#{post.updated_at}"```. You can use this key to expire it as you want,
293
+ but in this case it will be automatically expired after 3 hours.
294
+
295
+ ### Fragmenting Caching
296
+
297
+ If there is some API endpoint that shouldn't be fully cached, you can still optimise it, using Fragment Cache on the attributes and relationships that you want to cache.
298
+
299
+ You can define the attribute by using ```only``` or ```except``` option on cache method.
300
+
301
+ **[NOTE] Cache serializers will be used at their relationships**
302
+
303
+ Example:
304
+
305
+ ```ruby
306
+ class PostSerializer < ActiveModel::Serializer
307
+ cache key: 'post', expires_in: 3.hours, only: [:title]
308
+ attributes :title, :body
309
+
310
+ has_many :comments
311
+
312
+ url :post
313
+ end
314
+ ```
315
+
316
+ ## Getting Help
317
+
318
+ If you find a bug, please report an [Issue](https://github.com/rails-api/active_model_serializers/issues/new).
319
+
320
+ If you have a question, please [post to Stack Overflow](http://stackoverflow.com/questions/tagged/active-model-serializers).
321
+
322
+ Thanks!
323
+
324
+ # Contributing
325
+
326
+ See [CONTRIBUTING.md](https://github.com/rails-api/active_model_serializers/blob/master/CONTRIBUTING.md)