cm-active_model_serializers 0.10.0.rc1.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.
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)