gpi-active_model_serializers 0.8.2

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.
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+
2
+ if RUBY_VERSION =~ /1.9/ # assuming you're running Ruby ~1.9
3
+ Encoding.default_external = Encoding::UTF_8
4
+ Encoding.default_internal = Encoding::UTF_8
5
+ end
6
+
7
+ source 'https://rubygems.org'
8
+
9
+ # Specify gem dependencies in active_model_serializers.gemspec
10
+ gemspec
11
+
12
+ gem "coveralls", require: false
@@ -0,0 +1,9 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rails', github: 'rails/rails'
6
+
7
+ # Current dependencies of edge rails
8
+ gem 'journey', github: 'rails/journey'
9
+ gem 'activerecord-deprecated_finders' , github: 'rails/activerecord-deprecated_finders'
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2011-2012 José Valim & Yehuda Katz
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
@@ -0,0 +1,716 @@
1
+ [![Build Status](https://api.travis-ci.org/rails-api/active_model_serializers.png)](https://travis-ci.org/rails-api/active_model_serializers) [![Code Climate](https://codeclimate.com/github/rails-api/active_model_serializers.png)](https://codeclimate.com/github/rails-api/active_model_serializers) [![Coverage Status](https://coveralls.io/repos/rails-api/active_model_serializers/badge.png?branch=master)](https://coveralls.io/r/rails-api/active_model_serializers)
2
+
3
+ # Purpose
4
+
5
+ The purpose of `ActiveModel::Serializers` is to provide an object to
6
+ encapsulate serialization of `ActiveModel` objects, including `ActiveRecord`
7
+ objects.
8
+
9
+ Serializers know about both a model and the `current_user`, so you can
10
+ customize serialization based upon whether a user is authorized to see the
11
+ content.
12
+
13
+ In short, **serializers replace hash-driven development with object-oriented
14
+ development.**
15
+
16
+ # Installing
17
+
18
+ The easiest way to install `ActiveModel::Serializers` is to add it to your
19
+ `Gemfile`:
20
+
21
+ ```ruby
22
+ gem "active_model_serializers"
23
+ ```
24
+
25
+ Then, install it on the command line:
26
+
27
+ ```
28
+ $ bundle install
29
+ ```
30
+
31
+ #### Ruby 1.8 is no longer supported!
32
+
33
+ If you must use a ruby 1.8 version (MRI 1.8.7, REE, Rubinius 1.8, or JRuby 1.8), you need to use version 0.8.x.
34
+ Versions after 0.9.0 do not support ruby 1.8. To specify version 0.8, include this in your Gemfile:
35
+
36
+ ```ruby
37
+ gem "active_model_serializers", "~> 0.8.0"
38
+ ```
39
+
40
+
41
+ # Creating a Serializer
42
+
43
+ The easiest way to create a new serializer is to generate a new resource, which
44
+ will generate a serializer at the same time:
45
+
46
+ ```
47
+ $ rails g resource post title:string body:string
48
+ ```
49
+
50
+ This will generate a serializer in `app/serializers/post_serializer.rb` for
51
+ your new model. You can also generate a serializer for an existing model with
52
+ the serializer generator:
53
+
54
+ ```
55
+ $ rails g serializer post
56
+ ```
57
+
58
+ ### Support for POROs and other ORMs.
59
+
60
+ Currently `ActiveModel::Serializers` adds serialization support to all models
61
+ that descend from `ActiveRecord` or include `Mongoid::Document`. If you are
62
+ using another ORM, or if you are using objects that are `ActiveModel`
63
+ compliant but do not descend from `ActiveRecord` or include
64
+ `Mongoid::Document`, you must add an include statement for
65
+ `ActiveModel::SerializerSupport` to make models serializable. If you
66
+ also want to make collections serializable, you should include
67
+ `ActiveModel::ArraySerializerSupport` into your ORM's
68
+ relation/criteria class.
69
+
70
+ # ActiveModel::Serializer
71
+
72
+ All new serializers descend from ActiveModel::Serializer
73
+
74
+ # render :json
75
+
76
+ In your controllers, when you use `render :json`, Rails will now first search
77
+ for a serializer for the object and use it if available.
78
+
79
+ ```ruby
80
+ class PostsController < ApplicationController
81
+ def show
82
+ @post = Post.find(params[:id])
83
+ render json: @post
84
+ end
85
+ end
86
+ ```
87
+
88
+ In this case, Rails will look for a serializer named `PostSerializer`, and if
89
+ it exists, use it to serialize the `Post`.
90
+
91
+ This also works with `respond_with`, which uses `to_json` under the hood. Also
92
+ note that any options passed to `render :json` will be passed to your
93
+ serializer and available as `@options` inside.
94
+
95
+ To specify a custom serializer for an object, there are 2 options:
96
+
97
+ #### 1. Specify the serializer in your model:
98
+
99
+ ```ruby
100
+ class Post < ActiveRecord::Base
101
+ def active_model_serializer
102
+ FancyPostSerializer
103
+ end
104
+ end
105
+ ```
106
+
107
+ #### 2. Specify the serializer when you render the object:
108
+
109
+ ```ruby
110
+ render json: @post, serializer: FancyPostSerializer
111
+ ```
112
+
113
+ ## Arrays
114
+
115
+ In your controllers, when you use `render :json` for an array of objects, AMS will
116
+ use `ActiveModel::ArraySerializer` (included in this project) as the base serializer,
117
+ and the individual `Serializer` for the objects contained in that array.
118
+
119
+ ```ruby
120
+ class PostSerializer < ActiveModel::Serializer
121
+ attributes :title, :body
122
+ end
123
+
124
+ class PostsController < ApplicationController
125
+ def index
126
+ @posts = Post.all
127
+ render json: @posts
128
+ end
129
+ end
130
+ ```
131
+
132
+ Given the example above, the index action will return
133
+
134
+ ```json
135
+ {
136
+ "posts":
137
+ [
138
+ { "title": "Post 1", "body": "Hello!" },
139
+ { "title": "Post 2", "body": "Goodbye!" }
140
+ ]
141
+ }
142
+ ```
143
+
144
+ By default, the root element is the name of the controller. For example, `PostsController`
145
+ generates a root element "posts". To change it:
146
+
147
+ ```ruby
148
+ render json: @posts, root: "some_posts"
149
+ ```
150
+
151
+ You may disable the root element for arrays at the top level, which will result in
152
+ more concise json. See the next section for ways on how to do this. Disabling the
153
+ root element of the array with any of those methods will produce
154
+
155
+ ```json
156
+ [
157
+ { "title": "Post 1", "body": "Hello!" },
158
+ { "title": "Post 2", "body": "Goodbye!" }
159
+ ]
160
+ ```
161
+
162
+ To specify a custom serializer for the items within an array:
163
+
164
+ ```ruby
165
+ render json: @posts, each_serializer: FancyPostSerializer
166
+ ```
167
+
168
+ ## Disabling the root element
169
+
170
+ You have 4 options to disable the root element, each with a slightly different scope:
171
+
172
+ #### 1. Disable root globally for all, or per class
173
+
174
+ In an initializer:
175
+
176
+ ```ruby
177
+ ActiveSupport.on_load(:active_model_serializers) do
178
+ # Disable for all serializers (except ArraySerializer)
179
+ ActiveModel::Serializer.root = false
180
+
181
+ # Disable for ArraySerializer
182
+ ActiveModel::ArraySerializer.root = false
183
+ end
184
+ ```
185
+
186
+ #### 2. Disable root per render call in your controller
187
+
188
+ ```ruby
189
+ render json: @posts, root: false
190
+ ```
191
+
192
+ #### 3. Subclass the serializer, and specify using it
193
+
194
+ ```ruby
195
+ class CustomArraySerializer < ActiveModel::ArraySerializer
196
+ self.root = false
197
+ end
198
+
199
+ # controller:
200
+ render json: @posts, serializer: CustomArraySerializer
201
+ ```
202
+
203
+ #### 4. Define default_serializer_options in your controller
204
+
205
+ If you define `default_serializer_options` method in your controller,
206
+ all serializers in actions of this controller and it's children will use them.
207
+ One of the options may be `root: false`
208
+
209
+ ```ruby
210
+ def default_serializer_options
211
+ {
212
+ root: false
213
+ }
214
+ end
215
+ ```
216
+
217
+ ## Getting the old version
218
+
219
+ If you find that your project is already relying on the old rails to_json
220
+ change `render :json` to `render json: @your_object.to_json`.
221
+
222
+ # Attributes and Associations
223
+
224
+ Once you have a serializer, you can specify which attributes and associations
225
+ you would like to include in the serialized form.
226
+
227
+ ```ruby
228
+ class PostSerializer < ActiveModel::Serializer
229
+ attributes :id, :title, :body
230
+ has_many :comments
231
+ end
232
+ ```
233
+
234
+ ## Attributes
235
+
236
+ For specified attributes, a serializer will look up the attribute on the
237
+ object you passed to `render :json`. It uses
238
+ `read_attribute_for_serialization`, which `ActiveRecord` objects implement as a
239
+ regular attribute lookup.
240
+
241
+ Before looking up the attribute on the object, a serializer will check for the
242
+ presence of a method with the name of the attribute. This allows serializers to
243
+ include properties beyond the simple attributes of the model. For example:
244
+
245
+ ```ruby
246
+ class PersonSerializer < ActiveModel::Serializer
247
+ attributes :first_name, :last_name, :full_name
248
+
249
+ def full_name
250
+ "#{object.first_name} #{object.last_name}"
251
+ end
252
+ end
253
+ ```
254
+
255
+ Within a serializer's methods, you can access the object being
256
+ serialized as `object`.
257
+
258
+ Since this shadows any attribute named `object`, you can include them through `object.object`. For example:
259
+
260
+ ```ruby
261
+ class VersionSerializer < ActiveModel::Serializer
262
+ attribute :version_object, key: :object
263
+
264
+ def version_object
265
+ object.object
266
+ end
267
+ end
268
+ ```
269
+
270
+ You can also access the `current_user` method, which provides an
271
+ authorization context to your serializer. By default, the context
272
+ is the current user of your application, but this
273
+ [can be customized](#customizing-scope).
274
+
275
+ Serializers will check for the presence of a method named
276
+ `include_[ATTRIBUTE]?` to determine whether a particular attribute should be
277
+ included in the output. This is typically used to customize output
278
+ based on `current_user`. For example:
279
+
280
+ ```ruby
281
+ class PostSerializer < ActiveModel::Serializer
282
+ attributes :id, :title, :body, :author
283
+
284
+ def include_author?
285
+ current_user.admin?
286
+ end
287
+ end
288
+ ```
289
+
290
+ The type of a computed attribute (like :full_name above) is not easily
291
+ calculated without some sophisticated static code analysis. To specify the
292
+ type of a computed attribute:
293
+
294
+ ```ruby
295
+ class PersonSerializer < ActiveModel::Serializer
296
+ attributes :first_name, :last_name, {full_name: :string}
297
+
298
+ def full_name
299
+ "#{object.first_name} #{object.last_name}"
300
+ end
301
+ end
302
+ ```
303
+
304
+ If you would like the key in the outputted JSON to be different from its name
305
+ in ActiveRecord, you can use the `:key` option to customize it:
306
+
307
+ ```ruby
308
+ class PostSerializer < ActiveModel::Serializer
309
+ attributes :id, :body
310
+
311
+ # look up :subject on the model, but use +title+ in the JSON
312
+ attribute :subject, key: :title
313
+ has_many :comments
314
+ end
315
+ ```
316
+
317
+ If you would like to add meta information to the outputted JSON, use the `:meta`
318
+ option:
319
+
320
+ ```ruby
321
+ render json: @posts, serializer: CustomArraySerializer, meta: {total: 10}
322
+ ```
323
+
324
+ The above usage of `:meta` will produce the following:
325
+
326
+ ```json
327
+ {
328
+ "meta": { "total": 10 },
329
+ "posts": [
330
+ { "title": "Post 1", "body": "Hello!" },
331
+ { "title": "Post 2", "body": "Goodbye!" }
332
+ ]
333
+ }
334
+ ```
335
+
336
+ If you would like to change the meta key name you can use the `:meta_key` option:
337
+
338
+ ```ruby
339
+ render json: @posts, serializer: CustomArraySerializer, meta: {total: 10}, meta_key: 'meta_object'
340
+ ```
341
+
342
+ The above usage of `:meta_key` will produce the following:
343
+
344
+ ```json
345
+ {
346
+ "meta_object": { "total": 10 },
347
+ "posts": [
348
+ { "title": "Post 1", "body": "Hello!" },
349
+ { "title": "Post 2", "body": "Goodbye!" }
350
+ ]
351
+ }
352
+ ```
353
+
354
+ If you would like direct, low-level control of attribute serialization, you can
355
+ completely override the `attributes` method to return the hash you need:
356
+
357
+ ```ruby
358
+ class PersonSerializer < ActiveModel::Serializer
359
+ attributes :first_name, :last_name
360
+
361
+ def attributes
362
+ hash = super
363
+ if current_user.admin?
364
+ hash["ssn"] = object.ssn
365
+ hash["secret"] = object.mothers_maiden_name
366
+ end
367
+ hash
368
+ end
369
+ end
370
+ ```
371
+
372
+ ## Associations
373
+
374
+ For specified associations, the serializer will look up the association and
375
+ then serialize each element of the association. For instance, a `has_many
376
+ :comments` association will create a new `CommentSerializer` for each comment
377
+ and use it to serialize the comment.
378
+
379
+ By default, serializers simply look up the association on the original object.
380
+ You can customize this behavior by implementing a method with the name of the
381
+ association and returning a different Array. Often, you will do this to
382
+ customize the objects returned based on the current user.
383
+
384
+ ```ruby
385
+ class PostSerializer < ActiveModel::Serializer
386
+ attributes :id, :title, :body
387
+ has_many :comments
388
+
389
+ # only let the user see comments he created.
390
+ def comments
391
+ object.comments.where(created_by: current_user)
392
+ end
393
+ end
394
+ ```
395
+
396
+ As with attributes, you can change the JSON key that the serializer should
397
+ use for a particular association.
398
+
399
+ ```ruby
400
+ class PostSerializer < ActiveModel::Serializer
401
+ attributes :id, :title, :body
402
+
403
+ # look up comments, but use +my_comments+ as the key in JSON
404
+ has_many :comments, key: :my_comments
405
+ end
406
+ ```
407
+
408
+ Also, as with attributes, serializers will check for the presence
409
+ of a method named `include_[ASSOCIATION]?` to determine whether a particular association
410
+ should be included in the output. For example:
411
+
412
+ ```ruby
413
+ class PostSerializer < ActiveModel::Serializer
414
+ attributes :id, :title, :body
415
+ has_many :comments
416
+
417
+ def include_comments?
418
+ !object.comments_disabled?
419
+ end
420
+ end
421
+ ```
422
+
423
+ If you would like lower-level control of association serialization, you can
424
+ override `include_associations!` to specify which associations should be included:
425
+
426
+ ```ruby
427
+ class PostSerializer < ActiveModel::Serializer
428
+ attributes :id, :title, :body
429
+ has_one :author
430
+ has_many :comments
431
+
432
+ def include_associations!
433
+ include! :author if current_user.admin?
434
+ include! :comments unless object.comments_disabled?
435
+ end
436
+ end
437
+ ```
438
+
439
+ You may also use the `:serializer` option to specify a custom serializer class and the `:polymorphic` option to specify an association that is polymorphic (STI), e.g.:
440
+
441
+ ```ruby
442
+ has_many :comments, serializer: CommentShortSerializer
443
+ has_one :reviewer, polymorphic: true
444
+ ```
445
+
446
+ Serializers are only concerned with multiplicity, and not ownership. `belongs_to` ActiveRecord associations can be included using `has_one` in your serializer.
447
+
448
+ ## Embedding Associations
449
+
450
+ By default, associations will be embedded inside the serialized object. So if
451
+ you have a post, the outputted JSON will look like:
452
+
453
+ ```json
454
+ {
455
+ "post": {
456
+ "id": 1,
457
+ "title": "New post",
458
+ "body": "A body!",
459
+ "comments": [
460
+ { "id": 1, "body": "what a dumb post" }
461
+ ]
462
+ }
463
+ }
464
+ ```
465
+
466
+ This is convenient for simple use-cases, but for more complex clients, it is
467
+ better to supply an Array of IDs for the association. This makes your API more
468
+ flexible from a performance standpoint and avoids wasteful duplication.
469
+
470
+ To embed IDs instead of associations, simply use the `embed` class method:
471
+
472
+ ```ruby
473
+ class PostSerializer < ActiveModel::Serializer
474
+ embed :ids
475
+
476
+ attributes :id, :title, :body
477
+ has_many :comments
478
+ end
479
+ ```
480
+
481
+ Now, any associations will be supplied as an Array of IDs:
482
+
483
+ ```json
484
+ {
485
+ "post": {
486
+ "id": 1,
487
+ "title": "New post",
488
+ "body": "A body!",
489
+ "comment_ids": [ 1, 2, 3 ]
490
+ }
491
+ }
492
+ ```
493
+
494
+ Alternatively, you can choose to embed only the ids or the associated objects per association:
495
+
496
+ ```ruby
497
+ class PostSerializer < ActiveModel::Serializer
498
+ attributes :id, :title, :body
499
+
500
+ has_many :comments, embed: :objects
501
+ has_many :tags, embed: :ids
502
+ end
503
+ ```
504
+
505
+ The JSON will look like this:
506
+
507
+ ```json
508
+ {
509
+ "post": {
510
+ "id": 1,
511
+ "title": "New post",
512
+ "body": "A body!",
513
+ "comments": [
514
+ { "id": 1, "body": "what a dumb post" }
515
+ ],
516
+ "tag_ids": [ 1, 2, 3 ]
517
+ }
518
+ }
519
+ ```
520
+
521
+ In addition to supplying an Array of IDs, you may want to side-load the data
522
+ alongside the main object. This makes it easier to process the entire package
523
+ of data without having to recursively scan the tree looking for embedded
524
+ information. It also ensures that associations that are shared between several
525
+ objects (like tags), are only delivered once for the entire payload.
526
+
527
+ You can specify that the data be included like this:
528
+
529
+ ```ruby
530
+ class PostSerializer < ActiveModel::Serializer
531
+ embed :ids, include: true
532
+
533
+ attributes :id, :title, :body
534
+ has_many :comments
535
+ end
536
+ ```
537
+
538
+ Assuming that the comments also `has_many :tags`, you will get a JSON like
539
+ this:
540
+
541
+ ```json
542
+ {
543
+ "post": {
544
+ "id": 1,
545
+ "title": "New post",
546
+ "body": "A body!",
547
+ "comment_ids": [ 1, 2 ]
548
+ },
549
+ "comments": [
550
+ { "id": 1, "body": "what a dumb post", "tag_ids": [ 1, 2 ] },
551
+ { "id": 2, "body": "i liked it", "tag_ids": [ 1, 3 ] },
552
+ ],
553
+ "tags": [
554
+ { "id": 1, "name": "short" },
555
+ { "id": 2, "name": "whiny" },
556
+ { "id": 3, "name": "happy" }
557
+ ]
558
+ }
559
+ ```
560
+
561
+ You can also specify a different root for the embedded objects than the key
562
+ used to reference them:
563
+
564
+ ```ruby
565
+ class PostSerializer < ActiveModel::Serializer
566
+ embed :ids, include: true
567
+
568
+ attributes :id, :title, :body
569
+ has_many :comments, key: :comment_ids, root: :comment_objects
570
+ end
571
+ ```
572
+
573
+ This would generate JSON that would look like this:
574
+
575
+ ```json
576
+ {
577
+ "post": {
578
+ "id": 1,
579
+ "title": "New post",
580
+ "body": "A body!",
581
+ "comment_ids": [ 1 ]
582
+ },
583
+ "comment_objects": [
584
+ { "id": 1, "body": "what a dumb post" }
585
+ ]
586
+ }
587
+ ```
588
+
589
+ You can also specify a different attribute to use rather than the ID of the
590
+ objects:
591
+
592
+ ```ruby
593
+ class PostSerializer < ActiveModel::Serializer
594
+ embed :ids, include: true
595
+
596
+ attributes :id, :title, :body
597
+ has_many :comments, embed_key: :external_id
598
+ end
599
+ ```
600
+
601
+ This would generate JSON that would look like this:
602
+
603
+ ```json
604
+ {
605
+ "post": {
606
+ "id": 1,
607
+ "title": "New post",
608
+ "body": "A body!",
609
+ "comment_ids": [ "COMM001" ]
610
+ },
611
+ "comments": [
612
+ { "id": 1, "external_id": "COMM001", "body": "what a dumb post" }
613
+ ]
614
+ }
615
+ ```
616
+
617
+ **NOTE**: The `embed :ids` mechanism is primary useful for clients that process
618
+ data in bulk and load it into a local store. For these clients, the ability to
619
+ easily see all of the data per type, rather than having to recursively scan the
620
+ data looking for information, is extremely useful.
621
+
622
+ If you are mostly working with the data in simple scenarios and manually making
623
+ Ajax requests, you probably just want to use the default embedded behavior.
624
+
625
+ ## Customizing Scope
626
+
627
+ In a serializer, `current_user` is the current authorization scope which the controller
628
+ provides to the serializer when you call `render :json`. By default, this is
629
+ `current_user`, but can be customized in your controller by calling
630
+ `serialization_scope`:
631
+
632
+ ```ruby
633
+ class ApplicationController < ActionController::Base
634
+ serialization_scope :current_admin
635
+ end
636
+ ```
637
+
638
+ The above example will also change the scope name from `current_user` to
639
+ `current_admin`.
640
+
641
+ Please note that, until now, `serialization_scope` doesn't accept a second
642
+ object with options for specifying which actions should or should not take a
643
+ given scope in consideration.
644
+
645
+ To be clear, it's not possible, yet, to do something like this:
646
+
647
+ ```ruby
648
+ class SomeController < ApplicationController
649
+ serialization_scope :current_admin, except: [:index, :show]
650
+ end
651
+ ```
652
+
653
+ So, in order to have a fine grained control of what each action should take in
654
+ consideration for its scope, you may use something like this:
655
+
656
+ ```ruby
657
+ class CitiesController < ApplicationController
658
+ serialization_scope nil
659
+
660
+ def index
661
+ @cities = City.all
662
+
663
+ render json: @cities, each_serializer: CitySerializer
664
+ end
665
+
666
+ def show
667
+ @city = City.find(params[:id])
668
+
669
+ render json: @city, scope: current_admin, scope_name: :current_admin
670
+ end
671
+ end
672
+ ```
673
+
674
+ Assuming that the `current_admin` method needs to make a query in the database
675
+ for the current user, the advantage of this approach is that, by setting
676
+ `serialization_scope` to `nil`, the `index` action no longer will need to make
677
+ that query, only the `show` action will.
678
+
679
+ ## Caching
680
+
681
+ To cache a serializer, call `cached` and define a `cache_key` method:
682
+
683
+ ```ruby
684
+ class PostSerializer < ActiveModel::Serializer
685
+ cached # enables caching for this serializer
686
+
687
+ attributes :title, :body
688
+
689
+ def cache_key
690
+ [object, current_user]
691
+ end
692
+ end
693
+ ```
694
+
695
+ The caching interface uses `Rails.cache` under the hood.
696
+
697
+ # Design and Implementation
698
+
699
+ ## Keep it Simple
700
+
701
+ ActiveModel::Serializers is capable of producing complex JSON views/large object
702
+ trees, and it may be tempting to design in this way so that your client can make
703
+ fewer requests to get data and so that related querying can be optimized.
704
+ However, keeping things simple in your serializers and controllers may
705
+ significantly reduce complexity and maintenance over the long-term development
706
+ of your application. Please consider reducing the complexity of the JSON views
707
+ you provide via the serializers as you build out your application, so that
708
+ controllers/services can be more easily reused without a lot of complexity
709
+ later.
710
+
711
+ ## Performance
712
+
713
+ As you develop your controllers or other code that utilizes serializers, try to
714
+ avoid n+1 queries by ensuring that data loads in an optimal fashion, e.g. if you
715
+ are using ActiveRecord, you might want to use query includes or joins as needed
716
+ to make the data available that the serializer(s) need.