active_model_serializers 0.9.8 → 0.10.0.rc1
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 +5 -5
- data/.gitignore +21 -0
- data/.travis.yml +27 -0
- data/CHANGELOG.md +8 -200
- data/CONTRIBUTING.md +23 -12
- data/Gemfile +17 -0
- data/{MIT-LICENSE → LICENSE.txt} +3 -2
- data/README.md +151 -781
- data/Rakefile +12 -0
- data/active_model_serializers.gemspec +26 -0
- data/lib/action_controller/serialization.rb +30 -75
- data/lib/active_model/serializer.rb +192 -252
- data/lib/active_model/serializer/adapter.rb +87 -0
- data/lib/active_model/serializer/adapter/fragment_cache.rb +78 -0
- data/lib/active_model/serializer/adapter/json.rb +52 -0
- data/lib/active_model/serializer/adapter/json/fragment_cache.rb +15 -0
- data/lib/active_model/serializer/adapter/json_api.rb +152 -0
- data/lib/active_model/serializer/adapter/json_api/fragment_cache.rb +22 -0
- data/lib/active_model/serializer/adapter/null.rb +11 -0
- data/lib/active_model/serializer/array_serializer.rb +32 -0
- data/lib/active_model/serializer/configuration.rb +13 -0
- data/lib/active_model/serializer/fieldset.rb +40 -0
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model_serializers.rb +5 -7
- data/lib/generators/serializer/USAGE +6 -0
- data/lib/{active_model/serializer/generators → generators}/serializer/serializer_generator.rb +8 -8
- data/lib/{active_model/serializer/generators → generators}/serializer/templates/serializer.rb +2 -2
- data/test/action_controller/adapter_selector_test.rb +51 -0
- data/test/action_controller/explicit_serializer_test.rb +110 -0
- data/test/action_controller/json_api_linked_test.rb +173 -0
- data/test/action_controller/serialization_scope_name_test.rb +63 -0
- data/test/action_controller/serialization_test.rb +365 -0
- data/test/adapter/fragment_cache_test.rb +27 -0
- data/test/adapter/json/belongs_to_test.rb +41 -0
- data/test/adapter/json/collection_test.rb +59 -0
- data/test/adapter/json/has_many_test.rb +36 -0
- data/test/adapter/json_api/belongs_to_test.rb +147 -0
- data/test/adapter/json_api/collection_test.rb +89 -0
- data/test/adapter/json_api/has_many_embed_ids_test.rb +45 -0
- data/test/adapter/json_api/has_many_explicit_serializer_test.rb +98 -0
- data/test/adapter/json_api/has_many_test.rb +106 -0
- data/test/adapter/json_api/has_one_test.rb +59 -0
- data/test/adapter/json_api/linked_test.rb +257 -0
- data/test/adapter/json_test.rb +34 -0
- data/test/adapter/null_test.rb +25 -0
- data/test/adapter_test.rb +43 -0
- data/test/array_serializer_test.rb +29 -0
- data/test/fixtures/poro.rb +125 -142
- data/test/serializers/adapter_for_test.rb +50 -0
- data/test/serializers/associations_test.rb +106 -0
- data/test/serializers/attribute_test.rb +23 -0
- data/test/serializers/attributes_test.rb +28 -0
- data/test/serializers/cache_test.rb +128 -0
- data/test/serializers/configuration_test.rb +15 -0
- data/test/serializers/fieldset_test.rb +26 -0
- data/test/serializers/generators_test.rb +59 -0
- data/test/serializers/meta_test.rb +78 -0
- data/test/serializers/options_test.rb +21 -0
- data/test/serializers/serializer_for_test.rb +56 -0
- data/test/serializers/urls_test.rb +26 -0
- data/test/test_helper.rb +21 -4
- metadata +121 -159
- data/DESIGN.textile +0 -586
- data/lib/action_controller/serialization_test_case.rb +0 -79
- data/lib/active_model/array_serializer.rb +0 -68
- data/lib/active_model/default_serializer.rb +0 -28
- data/lib/active_model/serializable.rb +0 -59
- data/lib/active_model/serializable/utils.rb +0 -16
- data/lib/active_model/serializer/association.rb +0 -58
- data/lib/active_model/serializer/association/has_many.rb +0 -39
- data/lib/active_model/serializer/association/has_one.rb +0 -25
- data/lib/active_model/serializer/config.rb +0 -31
- data/lib/active_model/serializer/generators/resource_override.rb +0 -13
- data/lib/active_model/serializer/generators/serializer/USAGE +0 -9
- data/lib/active_model/serializer/generators/serializer/scaffold_controller_generator.rb +0 -14
- data/lib/active_model/serializer/generators/serializer/templates/controller.rb +0 -93
- data/lib/active_model/serializer/railtie.rb +0 -22
- data/lib/active_model/serializer_support.rb +0 -5
- data/lib/active_model_serializers/model/caching.rb +0 -25
- data/test/benchmark/app.rb +0 -60
- data/test/benchmark/benchmarking_support.rb +0 -67
- data/test/benchmark/bm_active_record.rb +0 -41
- data/test/benchmark/setup.rb +0 -75
- data/test/benchmark/tmp/miniprofiler/mp_timers_6eqewtfgrhitvq5gqm25 +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_8083sx03hu72pxz1a4d0 +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_fyz2gsml4z0ph9kpoy1c +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_hjry5rc32imd42oxoi48 +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_m8fpoz2cvt3g9agz0bs3 +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_p92m2drnj1i568u3sta0 +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_qg52tpca3uesdfguee9i +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_s15t1a6mvxe0z7vjv790 +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_timers_x8kal3d17nfds6vp4kcj +0 -0
- data/test/benchmark/tmp/miniprofiler/mp_views_127.0.0.1 +0 -0
- data/test/fixtures/active_record.rb +0 -96
- data/test/fixtures/template.html.erb +0 -1
- data/test/integration/action_controller/namespaced_serialization_test.rb +0 -105
- data/test/integration/action_controller/serialization_test.rb +0 -287
- data/test/integration/action_controller/serialization_test_case_test.rb +0 -71
- data/test/integration/active_record/active_record_test.rb +0 -94
- data/test/integration/generators/resource_generator_test.rb +0 -26
- data/test/integration/generators/scaffold_controller_generator_test.rb +0 -64
- data/test/integration/generators/serializer_generator_test.rb +0 -41
- data/test/test_app.rb +0 -14
- data/test/tmp/app/assets/javascripts/accounts.js +0 -2
- data/test/tmp/app/assets/stylesheets/accounts.css +0 -4
- data/test/tmp/app/controllers/accounts_controller.rb +0 -2
- data/test/tmp/app/helpers/accounts_helper.rb +0 -2
- data/test/tmp/app/serializers/account_serializer.rb +0 -3
- data/test/tmp/config/routes.rb +0 -1
- data/test/unit/active_model/array_serializer/except_test.rb +0 -18
- data/test/unit/active_model/array_serializer/key_format_test.rb +0 -18
- data/test/unit/active_model/array_serializer/meta_test.rb +0 -53
- data/test/unit/active_model/array_serializer/only_test.rb +0 -18
- data/test/unit/active_model/array_serializer/options_test.rb +0 -16
- data/test/unit/active_model/array_serializer/root_test.rb +0 -102
- data/test/unit/active_model/array_serializer/scope_test.rb +0 -24
- data/test/unit/active_model/array_serializer/serialization_test.rb +0 -216
- data/test/unit/active_model/default_serializer_test.rb +0 -13
- data/test/unit/active_model/serializer/associations/build_serializer_test.rb +0 -36
- data/test/unit/active_model/serializer/associations_test.rb +0 -49
- data/test/unit/active_model/serializer/attributes_test.rb +0 -57
- data/test/unit/active_model/serializer/config_test.rb +0 -91
- data/test/unit/active_model/serializer/filter_test.rb +0 -69
- data/test/unit/active_model/serializer/has_many_polymorphic_test.rb +0 -189
- data/test/unit/active_model/serializer/has_many_test.rb +0 -265
- data/test/unit/active_model/serializer/has_one_and_has_many_test.rb +0 -27
- data/test/unit/active_model/serializer/has_one_polymorphic_test.rb +0 -196
- data/test/unit/active_model/serializer/has_one_test.rb +0 -253
- data/test/unit/active_model/serializer/key_format_test.rb +0 -25
- data/test/unit/active_model/serializer/meta_test.rb +0 -39
- data/test/unit/active_model/serializer/options_test.rb +0 -42
- data/test/unit/active_model/serializer/root_test.rb +0 -117
- data/test/unit/active_model/serializer/scope_test.rb +0 -49
- data/test/unit/active_model/serializer/url_helpers_test.rb +0 -35
- data/test/unit/active_model/serilizable_test.rb +0 -50
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: e77127a346e9bfdfb4b48152c333394b5c5e2e41
|
|
4
|
+
data.tar.gz: cc4ba7acbb64a83d588e6da78c54ace9e9309734
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fca71a58180a630765a4628c9202b775fb855c36d517546a6fa122166944cd14d79e968369d7fdabce45c6bd585b55a3e9c17ccd72b8b1287fe8eff0b8507167
|
|
7
|
+
data.tar.gz: dafdf5f8c3f57bdbaf141d05573459bc14f314a0a5bc6a30f94eb8f8d6f2e8d29649ba34187112c27c819536dd77a7983715b066c83283ef1434a8ea333669ff
|
data/.gitignore
ADDED
|
@@ -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
|
data/.travis.yml
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
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=3.2"
|
|
19
|
+
- "RAILS_VERSION=4.0"
|
|
20
|
+
- "RAILS_VERSION=4.1"
|
|
21
|
+
- "RAILS_VERSION=master"
|
|
22
|
+
|
|
23
|
+
matrix:
|
|
24
|
+
allow_failures:
|
|
25
|
+
- rvm: ruby-head
|
|
26
|
+
- env: "RAILS_VERSION=master"
|
|
27
|
+
- env: "RAILS_VERSION=3.2"
|
data/CHANGELOG.md
CHANGED
|
@@ -1,200 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
### [v0.9.7 (2017-05-01)](https://github.com/rails-api/active_model_serializers/compare/v0.9.6...v0.9.7)
|
|
10
|
-
|
|
11
|
-
- [#2080](https://github.com/rails-api/active_model_serializers/pull/2080) remove `{ payload: nil }` from `!serialize.active_model_serializers` ActiveSupport::Notification. `payload` never had a value. Changes, for example `{ serializer: 'ActiveModel::DefaultSerializer', payload: nil }` to be `{ serializer: 'ActiveModel::DefaultSerializer' }` (@yosiat)
|
|
12
|
-
|
|
13
|
-
### [v0.9.6 (2017-01-10)](https://github.com/rails-api/active_model_serializers/compare/v0.9.5...v0.9.6)
|
|
14
|
-
|
|
15
|
-
- [#2008](https://github.com/rails-api/active_model_serializers/pull/2008) Fix warning on Thor. (@kirs)
|
|
16
|
-
|
|
17
|
-
### [v0.9.5 (2016-03-30)](https://github.com/rails-api/active_model_serializers/compare/v0.9.4...v0.9.5)
|
|
18
|
-
|
|
19
|
-
- [#1607](https://github.com/rails-api/active_model_serializers/pull/1607) Merge multiple nested associations. (@Hirtenknogger)
|
|
20
|
-
|
|
21
|
-
### [v0.9.4 (2016-01-05)](https://github.com/rails-api/active_model_serializers/compare/v0.9.3...v0.9.4)
|
|
22
|
-
|
|
23
|
-
- [#752](https://github.com/rails-api/active_model_serializers/pull/752) Tiny improvement of README 0-9-stable (@basiam)
|
|
24
|
-
- [#749](https://github.com/rails-api/active_model_serializers/pull/749) remove trailing whitespace (@shwoodard)
|
|
25
|
-
- [#717](https://github.com/rails-api/active_model_serializers/pull/717) fixed issue with rendering Hash which appears in rails 4.2.0.beta4 (@kurko, @greshny)
|
|
26
|
-
- [#790](https://github.com/rails-api/active_model_serializers/pull/790) pass context to ArraySerializer (@lanej)
|
|
27
|
-
- [#797](https://github.com/rails-api/active_model_serializers/pull/797) Fix and test for #490 (@afn)
|
|
28
|
-
- [#813](https://github.com/rails-api/active_model_serializers/pull/813) Allow to define custom serializer for given class (@jtomaszewski)
|
|
29
|
-
- [#841](https://github.com/rails-api/active_model_serializers/pull/841) Fix issue with embedding multiple associations under the same root key (@antstorm)
|
|
30
|
-
- [#748](https://github.com/rails-api/active_model_serializers/pull/748) Propagate serialization_options across associations (@raphaelpereira)
|
|
31
|
-
|
|
32
|
-
### [v0.9.3 (2015/01/21 20:29 +00:00)](https://github.com/rails-api/active_model_serializers/compare/v0.9.2...v0.9.3)
|
|
33
|
-
|
|
34
|
-
Features:
|
|
35
|
-
- [#774](https://github.com/rails-api/active_model_serializers/pull/774) Fix nested include attributes (@nhocki)
|
|
36
|
-
- [#771](https://github.com/rails-api/active_model_serializers/pull/771) Make linked resource type names consistent with root names (@sweatypitts)
|
|
37
|
-
- [#696](https://github.com/rails-api/active_model_serializers/pull/696) Explicitly set serializer for associations (@ggordon)
|
|
38
|
-
- [#700](https://github.com/rails-api/active_model_serializers/pull/700) sparse fieldsets (@arenoir)
|
|
39
|
-
- [#768](https://github.com/rails-api/active_model_serializers/pull/768) Adds support for `meta` and `meta_key` attribute (@kurko)
|
|
40
|
-
|
|
41
|
-
### [v0.9.2](https://github.com/rails-api/active_model_serializers/compare/v0.9.1...v0.9.2)
|
|
42
|
-
|
|
43
|
-
### [v0.9.1 (2014/12/04 11:54 +00:00)](https://github.com/rails-api/active_model_serializers/compare/v0.9.0...v0.9.1)
|
|
44
|
-
|
|
45
|
-
- [#707](https://github.com/rails-api/active_model_serializers/pull/707) A Friendly Note on Which AMS Version to Use (@jherdman)
|
|
46
|
-
- [#730](https://github.com/rails-api/active_model_serializers/pull/730) Fixes nested has_many links in JSONAPI (@kurko)
|
|
47
|
-
- [#718](https://github.com/rails-api/active_model_serializers/pull/718) Allow overriding the adapter with render option (@ggordon)
|
|
48
|
-
- [#720](https://github.com/rails-api/active_model_serializers/pull/720) Rename attribute with :key (0.8.x compatibility) (@ggordon)
|
|
49
|
-
- [#728](https://github.com/rails-api/active_model_serializers/pull/728) Use type as key for linked resources (@kurko)
|
|
50
|
-
- [#729](https://github.com/rails-api/active_model_serializers/pull/729) Use the new beta build env on Travis (@joshk)
|
|
51
|
-
- [#703](https://github.com/rails-api/active_model_serializers/pull/703) Support serializer and each_serializer options in renderer (@ggordon, @mieko)
|
|
52
|
-
- [#727](https://github.com/rails-api/active_model_serializers/pull/727) Includes links inside of linked resources (@kurko)
|
|
53
|
-
- [#726](https://github.com/rails-api/active_model_serializers/pull/726) Bugfix: include nested has_many associations (@kurko)
|
|
54
|
-
- [#722](https://github.com/rails-api/active_model_serializers/pull/722) Fix infinite recursion (@ggordon)
|
|
55
|
-
- [#1](https://github.com/rails-api/active_model_serializers/pull/1) Allow for the implicit use of ArraySerializer when :each_serializer is specified (@mieko)
|
|
56
|
-
- [#692](https://github.com/rails-api/active_model_serializers/pull/692) Include 'linked' member for json-api collections (@ggordon)
|
|
57
|
-
- [#714](https://github.com/rails-api/active_model_serializers/pull/714) Define as_json instead of to_json (@guilleiguaran)
|
|
58
|
-
- [#710](https://github.com/rails-api/active_model_serializers/pull/710) JSON-API: Don't include linked section if associations are empty (@guilleiguaran)
|
|
59
|
-
- [#711](https://github.com/rails-api/active_model_serializers/pull/711) Fixes rbx gems bundling on TravisCI (@kurko)
|
|
60
|
-
- [#709](https://github.com/rails-api/active_model_serializers/pull/709) Add type key when association name is different than object type (@guilleiguaran)
|
|
61
|
-
- [#708](https://github.com/rails-api/active_model_serializers/pull/708) Handle correctly null associations (@guilleiguaran)
|
|
62
|
-
- [#691](https://github.com/rails-api/active_model_serializers/pull/691) Fix embed option for associations (@jacob-s-son)
|
|
63
|
-
- [#689](https://github.com/rails-api/active_model_serializers/pull/689) Fix support for custom root in JSON-API adapter (@guilleiguaran)
|
|
64
|
-
- [#685](https://github.com/rails-api/active_model_serializers/pull/685) Serialize ids as strings in JSON-API adapter (@guilleiguaran)
|
|
65
|
-
- [#684](https://github.com/rails-api/active_model_serializers/pull/684) Refactor adapters to implement support for array serialization (@guilleiguaran)
|
|
66
|
-
- [#682](https://github.com/rails-api/active_model_serializers/pull/682) Include root by default in JSON-API serializers (@guilleiguaran)
|
|
67
|
-
- [#625](https://github.com/rails-api/active_model_serializers/pull/625) Add DSL for urls (@JordanFaust)
|
|
68
|
-
- [#677](https://github.com/rails-api/active_model_serializers/pull/677) Add support for embed: :ids option for in associations (@guilleiguaran)
|
|
69
|
-
- [#681](https://github.com/rails-api/active_model_serializers/pull/681) Check superclasses for Serializers (@quainjn)
|
|
70
|
-
- [#680](https://github.com/rails-api/active_model_serializers/pull/680) Add support for root keys (@NullVoxPopuli)
|
|
71
|
-
- [#675](https://github.com/rails-api/active_model_serializers/pull/675) Support Rails 4.2.0 (@tricknotes)
|
|
72
|
-
- [#667](https://github.com/rails-api/active_model_serializers/pull/667) Require only activemodel instead of full rails (@guilleiguaran)
|
|
73
|
-
- [#653](https://github.com/rails-api/active_model_serializers/pull/653) Add "_test" suffix to JsonApi::HasManyTest filename. (@alexgenco)
|
|
74
|
-
- [#631](https://github.com/rails-api/active_model_serializers/pull/631) Update build badge URL (@craiglittle)
|
|
75
|
-
|
|
76
|
-
### [v0.9.0](https://github.com/rails-api/active_model_serializers/compare/v0.9.0.alpha1...v0.9.0)
|
|
77
|
-
|
|
78
|
-
### [0.9.0.alpha1 - January 7, 2014](https://github.com/rails-api/active_model_serializers/compare/d72b66d4c...v0.9.0.alpha1)
|
|
79
|
-
|
|
80
|
-
### 0.9.0.pre
|
|
81
|
-
|
|
82
|
-
* The following methods were removed
|
|
83
|
-
- Model#active\_model\_serializer
|
|
84
|
-
- Serializer#include!
|
|
85
|
-
- Serializer#include?
|
|
86
|
-
- Serializer#attr\_disabled=
|
|
87
|
-
- Serializer#cache
|
|
88
|
-
- Serializer#perform\_caching
|
|
89
|
-
- Serializer#schema (needs more discussion)
|
|
90
|
-
- Serializer#attribute
|
|
91
|
-
- Serializer#include\_#{name}? (filter method added)
|
|
92
|
-
- Serializer#attributes (took a hash)
|
|
93
|
-
|
|
94
|
-
* The following things were added
|
|
95
|
-
- Serializer#filter method
|
|
96
|
-
- CONFIG object
|
|
97
|
-
|
|
98
|
-
* Remove support for ruby 1.8 versions.
|
|
99
|
-
|
|
100
|
-
* Require rails >= 3.2.
|
|
101
|
-
|
|
102
|
-
* Serializers for associations are being looked up in a parent serializer's namespace first. Same with controllers' namespaces.
|
|
103
|
-
|
|
104
|
-
* Added a "prefix" option in case you want to use a different version of serializer.
|
|
105
|
-
|
|
106
|
-
* Serializers default namespace can be set in `default_serializer_options` and inherited by associations.
|
|
107
|
-
|
|
108
|
-
# VERSION 0.9.0.pre
|
|
109
|
-
|
|
110
|
-
* The following methods were removed
|
|
111
|
-
- Model#active\_model\_serializer
|
|
112
|
-
- Serializer#include!
|
|
113
|
-
- Serializer#include?
|
|
114
|
-
- Serializer#attr\_disabled=
|
|
115
|
-
- Serializer#cache
|
|
116
|
-
- Serializer#perform\_caching
|
|
117
|
-
- Serializer#schema (needs more discussion)
|
|
118
|
-
- Serializer#attribute
|
|
119
|
-
- Serializer#include\_#{name}? (filter method added)
|
|
120
|
-
- Serializer#attributes (took a hash)
|
|
121
|
-
|
|
122
|
-
* The following things were added
|
|
123
|
-
- Serializer#filter method
|
|
124
|
-
- CONFIG object
|
|
125
|
-
|
|
126
|
-
* Remove support for ruby 1.8 versions.
|
|
127
|
-
|
|
128
|
-
* Require rails >= 3.2.
|
|
129
|
-
|
|
130
|
-
* Serializers for associations are being looked up in a parent serializer's namespace first. Same with controllers' namespaces.
|
|
131
|
-
|
|
132
|
-
* Added a "prefix" option in case you want to use a different version of serializer.
|
|
133
|
-
|
|
134
|
-
* Serializers default namespace can be set in `default_serializer_options` and inherited by associations.
|
|
135
|
-
|
|
136
|
-
# VERSION 0.8.1
|
|
137
|
-
|
|
138
|
-
* Fix bug whereby a serializer using 'options' would blow up.
|
|
139
|
-
|
|
140
|
-
# VERSION 0.8.0
|
|
141
|
-
|
|
142
|
-
* Attributes can now have optional types.
|
|
143
|
-
|
|
144
|
-
* A new DefaultSerializer ensures that POROs behave the same way as ActiveModels.
|
|
145
|
-
|
|
146
|
-
* If you wish to override ActiveRecord::Base#to\_Json, you can now require
|
|
147
|
-
'active\_record/serializer\_override'. We don't recommend you do this, but
|
|
148
|
-
many users do, so we've left it optional.
|
|
149
|
-
|
|
150
|
-
* Fixed a bug where ActionController wouldn't always have MimeResponds.
|
|
151
|
-
|
|
152
|
-
* An optional caching feature allows you to cache JSON & hashes that AMS uses.
|
|
153
|
-
Adding 'cached true' to your Serializers will turn on this cache.
|
|
154
|
-
|
|
155
|
-
* URL helpers used inside of Engines now work properly.
|
|
156
|
-
|
|
157
|
-
* Serializers now can filter attributes with `only` and `except`:
|
|
158
|
-
|
|
159
|
-
```
|
|
160
|
-
UserSerializer.new(user, only: [:first_name, :last_name])
|
|
161
|
-
UserSerializer.new(user, except: :first_name)
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
* Basic Mongoid support. We now include our mixins in the right place.
|
|
165
|
-
|
|
166
|
-
* On Ruby 1.8, we now generate an `id` method that properly serializes `id`
|
|
167
|
-
columns. See issue #127 for more.
|
|
168
|
-
|
|
169
|
-
* Add an alias for `scope` method to be the name of the context. By default
|
|
170
|
-
this is `current_user`. The name is automatically set when using
|
|
171
|
-
`serialization_scope` in the controller.
|
|
172
|
-
|
|
173
|
-
* Pass through serialization options (such as `:include`) when a model
|
|
174
|
-
has no serializer defined.
|
|
175
|
-
|
|
176
|
-
# VERSION 0.7.0
|
|
177
|
-
|
|
178
|
-
* ```embed_key``` option to allow embedding by attributes other than IDs
|
|
179
|
-
* Fix rendering nil with custom serializer
|
|
180
|
-
* Fix global ```self.root = false```
|
|
181
|
-
* Add support for specifying the serializer for an association as a String
|
|
182
|
-
* Able to specify keys on the attributes method
|
|
183
|
-
* Serializer Reloading via ActiveSupport::DescendantsTracker
|
|
184
|
-
* Reduce double map to once; Fixes datamapper eager loading.
|
|
185
|
-
|
|
186
|
-
# VERSION 0.6.0
|
|
187
|
-
|
|
188
|
-
* Serialize sets properly
|
|
189
|
-
* Add root option to ArraySerializer
|
|
190
|
-
* Support polymorphic associations
|
|
191
|
-
* Support :each_serializer in ArraySerializer
|
|
192
|
-
* Add `scope` method to easily access the scope in the serializer
|
|
193
|
-
* Fix regression with Rails 3.2.6; add Rails 4 support
|
|
194
|
-
* Allow serialization_scope to be disabled with serialization_scope nil
|
|
195
|
-
* Array serializer should support pure ruby objects besides serializers
|
|
196
|
-
|
|
197
|
-
# VERSION 0.5.0
|
|
198
|
-
|
|
199
|
-
* First tagged version
|
|
200
|
-
* Changes generators to always generate an ApplicationSerializer
|
|
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]
|
data/CONTRIBUTING.md
CHANGED
|
@@ -1,20 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
===================
|
|
1
|
+
## How can I help?
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
Everyone is encouraged to open issues that are affecting you: bugs, ideas, performance problems – everything helps!
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
The first place to start is by looking at our [GitHub Issues](https://github.com/rails-api/active_model_serializers/issues).
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
list](https://github.com/rails-api/active_model_serializers/issues).
|
|
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.
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
rails-api-core](https://groups.google.com/forum/#!forum/rails-api-core).
|
|
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).
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
pull request that implements it. Tests and docs would be nice.
|
|
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.
|
|
16
12
|
|
|
17
|
-
|
|
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).
|
|
18
14
|
|
|
19
|
-
|
|
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.
|
|
20
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.1"
|
|
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
|
data/{MIT-LICENSE → LICENSE.txt}
RENAMED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
Copyright (c)
|
|
1
|
+
Copyright (c) 2014 Steve Klabnik
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
2
4
|
|
|
3
5
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
6
|
a copy of this software and associated documentation files (the
|
|
@@ -18,4 +20,3 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
|
18
20
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
21
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
22
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
-
|
data/README.md
CHANGED
|
@@ -1,956 +1,326 @@
|
|
|
1
|
-
[](https://travis-ci.org/rails-api/active_model_serializers)
|
|
2
|
-
[](https://codeclimate.com/github/rails-api/active_model_serializers)
|
|
3
|
-
|
|
4
1
|
# ActiveModel::Serializers
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
`ActiveModel::Serializers` encapsulates the JSON serialization of objects.
|
|
9
|
-
Objects that respond to read\_attribute\_for\_serialization
|
|
10
|
-
(including `ActiveModel` and `ActiveRecord` objects) are supported.
|
|
11
|
-
|
|
12
|
-
Serializers know about both a model and the `current_user`, so you can
|
|
13
|
-
customize serialization based upon whether a user is authorized to see the
|
|
14
|
-
content.
|
|
15
|
-
|
|
16
|
-
In short, **serializers replace hash-driven development with object-oriented
|
|
17
|
-
development.**
|
|
18
|
-
|
|
19
|
-
# Installing
|
|
20
|
-
|
|
21
|
-
The easiest way to install `ActiveModel::Serializers` is to add it to your
|
|
22
|
-
`Gemfile`:
|
|
23
|
-
|
|
24
|
-
```ruby
|
|
25
|
-
gem "active_model_serializers"
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Then, install it on the command line:
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
$ bundle install
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
#### Ruby 1.8 is no longer supported!
|
|
35
|
-
|
|
36
|
-
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.
|
|
37
|
-
Versions after 0.9.0 do not support ruby 1.8. To specify version 0.8, include this in your Gemfile:
|
|
38
|
-
|
|
39
|
-
```ruby
|
|
40
|
-
gem "active_model_serializers", "~> 0.8.0"
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
# Creating a Serializer
|
|
45
|
-
|
|
46
|
-
The easiest way to create a new serializer is to generate a new resource, which
|
|
47
|
-
will generate a serializer at the same time:
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
$ rails g resource post title:string body:string
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
This will generate a serializer in `app/serializers/post_serializer.rb` for
|
|
54
|
-
your new model. You can also generate a serializer for an existing model with
|
|
55
|
-
the serializer generator:
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
$ rails g serializer post
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### Support for POROs
|
|
3
|
+
[](https://travis-ci.org/rails-api/active_model_serializers)
|
|
62
4
|
|
|
63
|
-
|
|
64
|
-
do to have your POROs supported.
|
|
5
|
+
ActiveModel::Serializers brings convention over configuration to your JSON generation.
|
|
65
6
|
|
|
66
|
-
|
|
67
|
-
|
|
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.
|
|
68
10
|
|
|
69
|
-
#
|
|
11
|
+
# RELEASE CANDIDATE, PLEASE READ
|
|
70
12
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
```ruby
|
|
75
|
-
class PostsController < ApplicationController
|
|
76
|
-
def show
|
|
77
|
-
@post = Post.find(params[:id])
|
|
78
|
-
render json: @post
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
```
|
|
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`.
|
|
82
16
|
|
|
83
|
-
|
|
84
|
-
|
|
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)
|
|
85
19
|
|
|
86
|
-
|
|
87
|
-
note that any options passed to `render :json` will be passed to your
|
|
88
|
-
serializer and available as `@serialization_options` inside.
|
|
20
|
+
## Example
|
|
89
21
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
```ruby
|
|
94
|
-
render json: @post, serializer: FancyPostSerializer
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### Use serialization outside of ActionController::Base
|
|
98
|
-
|
|
99
|
-
When controller does not inherit from ActionController::Base,
|
|
100
|
-
include Serialization module manually:
|
|
101
|
-
|
|
102
|
-
```ruby
|
|
103
|
-
class ApplicationController < ActionController::API
|
|
104
|
-
include ActionController::Serialization
|
|
105
|
-
end
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## Arrays
|
|
109
|
-
|
|
110
|
-
In your controllers, when you use `render :json` for an array of objects, AMS will
|
|
111
|
-
use `ActiveModel::ArraySerializer` (included in this project) as the base serializer,
|
|
112
|
-
and the individual `Serializer` for the objects contained in that array.
|
|
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:
|
|
113
25
|
|
|
114
26
|
```ruby
|
|
115
27
|
class PostSerializer < ActiveModel::Serializer
|
|
28
|
+
cache key: 'posts', expires_in: 3.hours
|
|
116
29
|
attributes :title, :body
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
class PostsController < ApplicationController
|
|
120
|
-
def index
|
|
121
|
-
@posts = Post.all
|
|
122
|
-
render json: @posts
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
Given the example above, the index action will return
|
|
128
|
-
|
|
129
|
-
```json
|
|
130
|
-
{
|
|
131
|
-
"posts":
|
|
132
|
-
[
|
|
133
|
-
{ "title": "Post 1", "body": "Hello!" },
|
|
134
|
-
{ "title": "Post 2", "body": "Goodbye!" }
|
|
135
|
-
]
|
|
136
|
-
}
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
By default, the root element is the name of the controller. For example, `PostsController`
|
|
140
|
-
generates a root element "posts". To change it:
|
|
141
30
|
|
|
142
|
-
|
|
143
|
-
render json: @posts, root: "some_posts"
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
You may disable the root element for arrays at the top level, which will result in
|
|
147
|
-
more concise json. See the next section for ways on how to do this. Disabling the
|
|
148
|
-
root element of the array with any of those methods will produce
|
|
149
|
-
|
|
150
|
-
```json
|
|
151
|
-
[
|
|
152
|
-
{ "title": "Post 1", "body": "Hello!" },
|
|
153
|
-
{ "title": "Post 2", "body": "Goodbye!" }
|
|
154
|
-
]
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
To specify a custom serializer for the items within an array:
|
|
158
|
-
|
|
159
|
-
```ruby
|
|
160
|
-
render json: @posts, each_serializer: FancyPostSerializer
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
## Render independently
|
|
164
|
-
|
|
165
|
-
By default the setting of serializer is in controller as described above which is the
|
|
166
|
-
recommended way. However, there may be cases you need to render the json object elsewhere
|
|
167
|
-
say in a helper or a view when controller is only for main object.
|
|
168
|
-
|
|
169
|
-
Then you can render the serialized JSON independently.
|
|
31
|
+
has_many :comments
|
|
170
32
|
|
|
171
|
-
|
|
172
|
-
def current_user_as_json_helper
|
|
173
|
-
CurrentUserSerializer.new(current_user).to_json
|
|
33
|
+
url :post
|
|
174
34
|
end
|
|
175
35
|
```
|
|
176
36
|
|
|
177
|
-
|
|
37
|
+
and
|
|
178
38
|
|
|
179
39
|
```ruby
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
end
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
## Disabling the root element
|
|
187
|
-
|
|
188
|
-
You have 4 options to disable the root element, each with a slightly different scope:
|
|
189
|
-
|
|
190
|
-
#### 1. Disable root globally for all, or per class
|
|
191
|
-
|
|
192
|
-
In an initializer:
|
|
193
|
-
|
|
194
|
-
```ruby
|
|
195
|
-
# Disable for all serializers (except ArraySerializer)
|
|
196
|
-
ActiveModel::Serializer.root = false
|
|
197
|
-
|
|
198
|
-
# Disable for ArraySerializer
|
|
199
|
-
ActiveModel::ArraySerializer.root = false
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
#### 2. Disable root per render call in your controller
|
|
203
|
-
|
|
204
|
-
```ruby
|
|
205
|
-
render json: @posts, root: false
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
#### 3. Subclass the serializer, and specify using it
|
|
209
|
-
|
|
210
|
-
```ruby
|
|
211
|
-
class CustomArraySerializer < ActiveModel::ArraySerializer
|
|
212
|
-
self.root = false
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
# controller:
|
|
216
|
-
render json: @posts, serializer: CustomArraySerializer
|
|
217
|
-
```
|
|
40
|
+
class CommentSerializer < ActiveModel::Serializer
|
|
41
|
+
attributes :name, :body
|
|
218
42
|
|
|
219
|
-
|
|
43
|
+
belongs_to :post
|
|
220
44
|
|
|
221
|
-
|
|
222
|
-
all serializers in actions of this controller and it's children will use them.
|
|
223
|
-
One of the options may be `root: false`
|
|
224
|
-
|
|
225
|
-
```ruby
|
|
226
|
-
def default_serializer_options
|
|
227
|
-
{
|
|
228
|
-
root: false
|
|
229
|
-
}
|
|
45
|
+
url [:post, :comment]
|
|
230
46
|
end
|
|
231
47
|
```
|
|
232
48
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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:
|
|
236
52
|
|
|
237
53
|
```ruby
|
|
238
|
-
|
|
239
|
-
ActiveModel::Serializer.setup do |config|
|
|
240
|
-
config.key_format = :lower_camel
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
class BlogLowerCamelSerializer < ActiveModel::Serializer
|
|
244
|
-
format_keys :lower_camel
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
BlogSerializer.new(object, key_format: :lower_camel)
|
|
54
|
+
ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::JsonApi
|
|
248
55
|
```
|
|
249
56
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
You can specify that serializers use unsuffixed names as association keys by default.
|
|
57
|
+
or
|
|
253
58
|
|
|
254
59
|
```ruby
|
|
255
|
-
ActiveModel::Serializer.
|
|
256
|
-
config.default_key_type = :name
|
|
257
|
-
end
|
|
60
|
+
ActiveModel::Serializer.config.adapter = :json_api
|
|
258
61
|
```
|
|
259
62
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
## Getting the old version
|
|
263
|
-
|
|
264
|
-
If you find that your project is already relying on the old rails to_json
|
|
265
|
-
change `render :json` to `render json: @your_object.to_json`.
|
|
63
|
+
You won't need to implement an adapter unless you wish to use a new format or
|
|
64
|
+
media type with AMS.
|
|
266
65
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
Once you have a serializer, you can specify which attributes and associations
|
|
270
|
-
you would like to include in the serialized form.
|
|
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:
|
|
271
67
|
|
|
272
68
|
```ruby
|
|
273
69
|
class PostSerializer < ActiveModel::Serializer
|
|
274
|
-
attributes :id, :
|
|
70
|
+
attributes :id, :body
|
|
71
|
+
|
|
72
|
+
# look up :subject on the model, but use +title+ in the JSON
|
|
73
|
+
attribute :subject, :key => :title
|
|
275
74
|
has_many :comments
|
|
276
75
|
end
|
|
277
76
|
```
|
|
278
77
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
For specified attributes, a serializer will look up the attribute on the
|
|
282
|
-
object you passed to `render :json`. It uses
|
|
283
|
-
`read_attribute_for_serialization`, which `ActiveRecord` objects implement as a
|
|
284
|
-
regular attribute lookup.
|
|
285
|
-
|
|
286
|
-
Before looking up the attribute on the object, a serializer will check for the
|
|
287
|
-
presence of a method with the name of the attribute. This allows serializers to
|
|
288
|
-
include properties beyond the simple attributes of the model. For example:
|
|
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.
|
|
289
80
|
|
|
290
81
|
```ruby
|
|
291
|
-
class
|
|
292
|
-
|
|
82
|
+
class PostsController < ApplicationController
|
|
83
|
+
def show
|
|
84
|
+
@post = Post.find(params[:id])
|
|
293
85
|
|
|
294
|
-
|
|
295
|
-
"#{object.first_name} #{object.last_name}"
|
|
86
|
+
render json: @post
|
|
296
87
|
end
|
|
297
88
|
end
|
|
298
89
|
```
|
|
299
90
|
|
|
300
|
-
|
|
301
|
-
|
|
91
|
+
In this case, Rails will look for a serializer named `PostSerializer`, and if
|
|
92
|
+
it exists, use it to serialize the `Post`.
|
|
302
93
|
|
|
303
|
-
|
|
94
|
+
### Specify a serializer
|
|
304
95
|
|
|
305
|
-
|
|
306
|
-
class VersionSerializer < ActiveModel::Serializer
|
|
307
|
-
attributes :version_object
|
|
96
|
+
If you wish to use a serializer other than the default, you can explicitly pass it to the renderer.
|
|
308
97
|
|
|
309
|
-
|
|
310
|
-
object.object
|
|
311
|
-
end
|
|
312
|
-
end
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
You can also access the `scope` method, which provides an
|
|
316
|
-
authorization context to your serializer. By default, the context
|
|
317
|
-
is the current user of your application, but this
|
|
318
|
-
[can be customized](#customizing-scope).
|
|
319
|
-
|
|
320
|
-
Serializers provide a method named `filter`, which should return an array
|
|
321
|
-
used to determine what attributes and associations should be included in the output.
|
|
322
|
-
This is typically used to customize output based on `current_user`. For example:
|
|
98
|
+
#### 1. For a resource:
|
|
323
99
|
|
|
324
100
|
```ruby
|
|
325
|
-
|
|
326
|
-
attributes :id, :title, :body, :author
|
|
327
|
-
|
|
328
|
-
def filter(keys)
|
|
329
|
-
if scope.admin?
|
|
330
|
-
keys
|
|
331
|
-
else
|
|
332
|
-
keys - [:author]
|
|
333
|
-
end
|
|
334
|
-
end
|
|
335
|
-
end
|
|
101
|
+
render json: @post, serializer: PostPreviewSerializer
|
|
336
102
|
```
|
|
337
103
|
|
|
338
|
-
|
|
339
|
-
in case you want to avoid creating two extra arrays. Note that if you do an
|
|
340
|
-
in-place modification, you still need to return the modified array.
|
|
341
|
-
|
|
342
|
-
### Alias Attribute
|
|
343
|
-
If you would like the key in the outputted JSON to be different from its name
|
|
344
|
-
in ActiveRecord, you can declare the attribute with the different name
|
|
345
|
-
and redefine that method:
|
|
104
|
+
#### 2. For an array resource:
|
|
346
105
|
|
|
347
106
|
```ruby
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
object.subject
|
|
352
|
-
end
|
|
107
|
+
# Use the default `ArraySerializer`, which will use `each_serializer` to
|
|
108
|
+
# serialize each element
|
|
109
|
+
render json: @posts, each_serializer: PostPreviewSerializer
|
|
353
110
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
end
|
|
111
|
+
# Or, you can explicitly provide the collection serializer as well
|
|
112
|
+
render json: @posts, serializer: PaginatedSerializer, each_serializer: PostPreviewSerializer
|
|
357
113
|
```
|
|
358
114
|
|
|
359
|
-
|
|
360
|
-
option:
|
|
115
|
+
### Meta
|
|
361
116
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
```
|
|
117
|
+
If you want a `meta` attribute in your response, specify it in the `render`
|
|
118
|
+
call:
|
|
365
119
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
```json
|
|
369
|
-
{
|
|
370
|
-
"meta": { "total": 10 },
|
|
371
|
-
"posts": [
|
|
372
|
-
{ "title": "Post 1", "body": "Hello!" },
|
|
373
|
-
{ "title": "Post 2", "body": "Goodbye!" }
|
|
374
|
-
]
|
|
375
|
-
}
|
|
120
|
+
```ruby
|
|
121
|
+
render json: @post, meta: { total: 10 }
|
|
376
122
|
```
|
|
377
123
|
|
|
378
|
-
|
|
124
|
+
The key can be customized using `meta_key` option.
|
|
379
125
|
|
|
380
126
|
```ruby
|
|
381
|
-
render json: @
|
|
127
|
+
render json: @post, meta: { total: 10 }, meta_key: "custom_meta"
|
|
382
128
|
```
|
|
383
129
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
```json
|
|
387
|
-
{
|
|
388
|
-
"meta_object": { "total": 10 },
|
|
389
|
-
"posts": [
|
|
390
|
-
{ "title": "Post 1", "body": "Hello!" },
|
|
391
|
-
{ "title": "Post 2", "body": "Goodbye!" }
|
|
392
|
-
]
|
|
393
|
-
}
|
|
394
|
-
```
|
|
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.
|
|
395
132
|
|
|
396
|
-
|
|
397
|
-
invalid JSON. If you do not have a root key, the meta information will be ignored.
|
|
133
|
+
### Root key
|
|
398
134
|
|
|
399
|
-
If you
|
|
400
|
-
|
|
135
|
+
If you want to define a custom root for your response, specify it in the `render`
|
|
136
|
+
call:
|
|
401
137
|
|
|
402
138
|
```ruby
|
|
403
|
-
|
|
404
|
-
attributes :first_name, :last_name
|
|
405
|
-
|
|
406
|
-
def attributes
|
|
407
|
-
hash = super
|
|
408
|
-
if scope.admin?
|
|
409
|
-
hash["ssn"] = object.ssn
|
|
410
|
-
hash["secret"] = object.mothers_maiden_name
|
|
411
|
-
end
|
|
412
|
-
hash
|
|
413
|
-
end
|
|
414
|
-
end
|
|
139
|
+
render json: @post, root: "articles"
|
|
415
140
|
```
|
|
416
141
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
For specified associations, the serializer will look up the association and
|
|
420
|
-
then serialize each element of the association. For instance, a `has_many
|
|
421
|
-
:comments` association will create a new `CommentSerializer` for each comment
|
|
422
|
-
and use it to serialize the comment.
|
|
142
|
+
### Overriding association methods
|
|
423
143
|
|
|
424
|
-
|
|
425
|
-
You can customize this behavior by implementing a method with the name of the
|
|
426
|
-
association and returning a different Array. Often, you will do this to
|
|
427
|
-
customize the objects returned based on the current user (scope).
|
|
144
|
+
If you want to override any association, you can use:
|
|
428
145
|
|
|
429
146
|
```ruby
|
|
430
147
|
class PostSerializer < ActiveModel::Serializer
|
|
431
|
-
attributes :id, :
|
|
148
|
+
attributes :id, :body
|
|
149
|
+
|
|
432
150
|
has_many :comments
|
|
433
151
|
|
|
434
|
-
# only let the user see comments he created.
|
|
435
152
|
def comments
|
|
436
|
-
object.comments.
|
|
153
|
+
object.comments.active
|
|
437
154
|
end
|
|
438
155
|
end
|
|
439
156
|
```
|
|
440
157
|
|
|
441
|
-
|
|
442
|
-
use for a particular association.
|
|
158
|
+
### Overriding attribute methods
|
|
443
159
|
|
|
444
|
-
|
|
445
|
-
class PostSerializer < ActiveModel::Serializer
|
|
446
|
-
attributes :id, :title, :body
|
|
447
|
-
|
|
448
|
-
# look up comments, but use +my_comments+ as the key in JSON
|
|
449
|
-
has_many :comments, root: :my_comments
|
|
450
|
-
end
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
Also, as with attributes, serializers will execute a filter method to
|
|
454
|
-
determine which associations should be included in the output. For
|
|
455
|
-
example:
|
|
160
|
+
If you want to override any attribute, you can use:
|
|
456
161
|
|
|
457
162
|
```ruby
|
|
458
163
|
class PostSerializer < ActiveModel::Serializer
|
|
459
|
-
attributes :id, :
|
|
164
|
+
attributes :id, :body
|
|
165
|
+
|
|
460
166
|
has_many :comments
|
|
461
167
|
|
|
462
|
-
def
|
|
463
|
-
|
|
464
|
-
keys
|
|
168
|
+
def body
|
|
169
|
+
object.body.downcase
|
|
465
170
|
end
|
|
466
171
|
end
|
|
467
172
|
```
|
|
468
173
|
|
|
469
|
-
|
|
174
|
+
### Built in Adapters
|
|
470
175
|
|
|
471
|
-
|
|
472
|
-
class PostSerializer < ActiveModel::Serializer
|
|
473
|
-
attributes :id, :title, :body
|
|
474
|
-
has_one :author
|
|
475
|
-
has_many :comments
|
|
176
|
+
#### JSONAPI
|
|
476
177
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
end
|
|
482
|
-
end
|
|
483
|
-
```
|
|
484
|
-
|
|
485
|
-
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.:
|
|
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.
|
|
486
182
|
|
|
487
183
|
```ruby
|
|
488
|
-
|
|
489
|
-
|
|
184
|
+
render @posts, include: ['authors', 'comments']
|
|
185
|
+
# or
|
|
186
|
+
render @posts, include: 'authors,comments'
|
|
490
187
|
```
|
|
491
188
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
## Embedding Associations
|
|
189
|
+
## Installation
|
|
495
190
|
|
|
496
|
-
|
|
497
|
-
you have a post, the outputted JSON will look like:
|
|
191
|
+
Add this line to your application's Gemfile:
|
|
498
192
|
|
|
499
|
-
```
|
|
500
|
-
|
|
501
|
-
"post": {
|
|
502
|
-
"id": 1,
|
|
503
|
-
"title": "New post",
|
|
504
|
-
"body": "A body!",
|
|
505
|
-
"comments": [
|
|
506
|
-
{ "id": 1, "body": "what a dumb post" }
|
|
507
|
-
]
|
|
508
|
-
}
|
|
509
|
-
}
|
|
193
|
+
```
|
|
194
|
+
gem 'active_model_serializers'
|
|
510
195
|
```
|
|
511
196
|
|
|
512
|
-
|
|
513
|
-
better to supply an Array of IDs for the association. This makes your API more
|
|
514
|
-
flexible from a performance standpoint and avoids wasteful duplication.
|
|
515
|
-
|
|
516
|
-
To embed IDs instead of associations, simply use the `embed` class method:
|
|
517
|
-
|
|
518
|
-
```ruby
|
|
519
|
-
class PostSerializer < ActiveModel::Serializer
|
|
520
|
-
embed :ids
|
|
197
|
+
And then execute:
|
|
521
198
|
|
|
522
|
-
attributes :id, :title, :body
|
|
523
|
-
has_many :comments
|
|
524
|
-
end
|
|
525
199
|
```
|
|
526
|
-
|
|
527
|
-
Now, any associations will be supplied as an Array of IDs:
|
|
528
|
-
|
|
529
|
-
```json
|
|
530
|
-
{
|
|
531
|
-
"post": {
|
|
532
|
-
"id": 1,
|
|
533
|
-
"title": "New post",
|
|
534
|
-
"body": "A body!",
|
|
535
|
-
"comment_ids": [ 1, 2, 3 ]
|
|
536
|
-
}
|
|
537
|
-
}
|
|
200
|
+
$ bundle
|
|
538
201
|
```
|
|
539
202
|
|
|
540
|
-
|
|
541
|
-
`key` for the resource. For example, say we want to change `comment_ids`
|
|
542
|
-
to `comments` underneath a `links` key:
|
|
203
|
+
## Creating a Serializer
|
|
543
204
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
attributes :id, :title, :body
|
|
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:
|
|
547
207
|
|
|
548
|
-
has_many :comments, embed: :ids, key: :comments, embed_namespace: :links
|
|
549
|
-
end
|
|
550
208
|
```
|
|
551
|
-
|
|
552
|
-
The JSON will look like this:
|
|
553
|
-
|
|
554
|
-
```json
|
|
555
|
-
{
|
|
556
|
-
"post": {
|
|
557
|
-
"id": 1,
|
|
558
|
-
"title": "New post",
|
|
559
|
-
"body": "A body!",
|
|
560
|
-
"links": {
|
|
561
|
-
"comments": [ 1, 2, 3 ]
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
}
|
|
209
|
+
$ rails g resource post title:string body:string
|
|
565
210
|
```
|
|
566
211
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
class PostSerializer < ActiveModel::Serializer
|
|
571
|
-
attributes :id, :title, :body
|
|
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:
|
|
572
215
|
|
|
573
|
-
has_many :comments, embed: :objects
|
|
574
|
-
has_many :tags, embed: :ids
|
|
575
|
-
end
|
|
576
216
|
```
|
|
577
|
-
|
|
578
|
-
The JSON will look like this:
|
|
579
|
-
|
|
580
|
-
```json
|
|
581
|
-
{
|
|
582
|
-
"post": {
|
|
583
|
-
"id": 1,
|
|
584
|
-
"title": "New post",
|
|
585
|
-
"body": "A body!",
|
|
586
|
-
"comments": [
|
|
587
|
-
{ "id": 1, "body": "what a dumb post" }
|
|
588
|
-
],
|
|
589
|
-
"tag_ids": [ 1, 2, 3 ]
|
|
590
|
-
}
|
|
591
|
-
}
|
|
217
|
+
$ rails g serializer post
|
|
592
218
|
```
|
|
593
219
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
of data without having to recursively scan the tree looking for embedded
|
|
597
|
-
information. It also ensures that associations that are shared between several
|
|
598
|
-
objects (like tags), are only delivered once for the entire payload.
|
|
599
|
-
|
|
600
|
-
You can specify that the data be included like this:
|
|
220
|
+
The generated seralizer will contain basic `attributes` and
|
|
221
|
+
`has_many`/`has_one`/`belongs_to` declarations, based on the model. For example:
|
|
601
222
|
|
|
602
223
|
```ruby
|
|
603
224
|
class PostSerializer < ActiveModel::Serializer
|
|
604
|
-
|
|
225
|
+
attributes :title, :body
|
|
605
226
|
|
|
606
|
-
attributes :id, :title, :body
|
|
607
227
|
has_many :comments
|
|
608
|
-
|
|
609
|
-
```
|
|
610
|
-
|
|
611
|
-
Assuming that the comments also `has_many :tags`, you will get a JSON like
|
|
612
|
-
this:
|
|
613
|
-
|
|
614
|
-
```json
|
|
615
|
-
{
|
|
616
|
-
"post": {
|
|
617
|
-
"id": 1,
|
|
618
|
-
"title": "New post",
|
|
619
|
-
"body": "A body!",
|
|
620
|
-
"comment_ids": [ 1, 2 ]
|
|
621
|
-
},
|
|
622
|
-
"comments": [
|
|
623
|
-
{ "id": 1, "body": "what a dumb post", "tag_ids": [ 1, 2 ] },
|
|
624
|
-
{ "id": 2, "body": "i liked it", "tag_ids": [ 1, 3 ] },
|
|
625
|
-
],
|
|
626
|
-
"tags": [
|
|
627
|
-
{ "id": 1, "name": "short" },
|
|
628
|
-
{ "id": 2, "name": "whiny" },
|
|
629
|
-
{ "id": 3, "name": "happy" }
|
|
630
|
-
]
|
|
631
|
-
}
|
|
632
|
-
```
|
|
633
|
-
|
|
634
|
-
If you would like to namespace association JSON underneath a certain key in
|
|
635
|
-
the root document (say, `linked`), you can specify an `embed_in_root_key`:
|
|
636
|
-
|
|
637
|
-
```ruby
|
|
638
|
-
class PostSerializer < ActiveModel::Serializer
|
|
639
|
-
embed :ids, include: true, embed_in_root_key: :linked
|
|
228
|
+
has_one :author
|
|
640
229
|
|
|
641
|
-
|
|
642
|
-
has_many :comments, :tags
|
|
230
|
+
url :post
|
|
643
231
|
end
|
|
644
232
|
```
|
|
645
233
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
```json
|
|
649
|
-
{
|
|
650
|
-
"post": {
|
|
651
|
-
"id": 1,
|
|
652
|
-
"title": "New post",
|
|
653
|
-
"body": "A body!",
|
|
654
|
-
"comment_ids": [ 1, 2 ]
|
|
655
|
-
},
|
|
656
|
-
"linked": {
|
|
657
|
-
"comments": [
|
|
658
|
-
{ "id": 1, "body": "what a dumb post", "tag_ids": [ 1, 2 ] },
|
|
659
|
-
{ "id": 2, "body": "i liked it", "tag_ids": [ 1, 3 ] },
|
|
660
|
-
],
|
|
661
|
-
"tags": [
|
|
662
|
-
{ "id": 1, "name": "short" },
|
|
663
|
-
{ "id": 2, "name": "whiny" },
|
|
664
|
-
{ "id": 3, "name": "happy" }
|
|
665
|
-
]
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
```
|
|
669
|
-
|
|
670
|
-
When side-loading data, your serializer cannot have the `{ root: false }` option,
|
|
671
|
-
as this would lead to invalid JSON. If you do not have a root key, the `include`
|
|
672
|
-
instruction will be ignored
|
|
673
|
-
|
|
674
|
-
You can also specify a different root for the embedded objects than the key
|
|
675
|
-
used to reference them:
|
|
234
|
+
and
|
|
676
235
|
|
|
677
236
|
```ruby
|
|
678
|
-
class
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
attributes :id, :title, :body
|
|
682
|
-
has_many :comments, key: :comment_ids, root: :comment_objects
|
|
683
|
-
end
|
|
684
|
-
```
|
|
685
|
-
|
|
686
|
-
This would generate JSON that would look like this:
|
|
687
|
-
|
|
688
|
-
```json
|
|
689
|
-
{
|
|
690
|
-
"post": {
|
|
691
|
-
"id": 1,
|
|
692
|
-
"title": "New post",
|
|
693
|
-
"body": "A body!",
|
|
694
|
-
"comment_ids": [ 1 ]
|
|
695
|
-
},
|
|
696
|
-
"comment_objects": [
|
|
697
|
-
{ "id": 1, "body": "what a dumb post" }
|
|
698
|
-
]
|
|
699
|
-
}
|
|
700
|
-
```
|
|
237
|
+
class CommentSerializer < ActiveModel::Serializer
|
|
238
|
+
attributes :name, :body
|
|
701
239
|
|
|
702
|
-
|
|
703
|
-
objects:
|
|
240
|
+
belongs_to :post_id
|
|
704
241
|
|
|
705
|
-
|
|
706
|
-
class PostSerializer < ActiveModel::Serializer
|
|
707
|
-
embed :ids, include: true
|
|
708
|
-
|
|
709
|
-
attributes :id, :title, :body
|
|
710
|
-
has_many :comments, key: :external_id
|
|
242
|
+
url [:post, :comment]
|
|
711
243
|
end
|
|
712
244
|
```
|
|
713
245
|
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
```json
|
|
717
|
-
{
|
|
718
|
-
"post": {
|
|
719
|
-
"id": 1,
|
|
720
|
-
"title": "New post",
|
|
721
|
-
"body": "A body!",
|
|
722
|
-
"comment_ids": [ "COMM001" ]
|
|
723
|
-
},
|
|
724
|
-
"comments": [
|
|
725
|
-
{ "id": 1, "external_id": "COMM001", "body": "what a dumb post" }
|
|
726
|
-
]
|
|
727
|
-
}
|
|
728
|
-
```
|
|
729
|
-
|
|
730
|
-
**NOTE**: The `embed :ids` mechanism is primary useful for clients that process
|
|
731
|
-
data in bulk and load it into a local store. For these clients, the ability to
|
|
732
|
-
easily see all of the data per type, rather than having to recursively scan the
|
|
733
|
-
data looking for information, is extremely useful.
|
|
734
|
-
|
|
735
|
-
If you are mostly working with the data in simple scenarios and manually making
|
|
736
|
-
Ajax requests, you probably just want to use the default embedded behavior.
|
|
246
|
+
The attribute names are a **whitelist** of attributes to be serialized.
|
|
737
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.
|
|
738
251
|
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
Because we need both the id and the type to be able to identify a polymorphic associated model, these are serialized in a slightly different format than common ones.
|
|
742
|
-
|
|
743
|
-
When embedding entire objects:
|
|
252
|
+
You may also use the `:serializer` option to specify a custom serializer class, for example:
|
|
744
253
|
|
|
745
254
|
```ruby
|
|
746
|
-
|
|
747
|
-
attributes :id, :title
|
|
748
|
-
has_many :attachments, polymorphic: true
|
|
749
|
-
end
|
|
255
|
+
has_many :comments, serializer: CommentPreviewSerializer
|
|
750
256
|
```
|
|
751
257
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
"post": {
|
|
755
|
-
"id": 1,
|
|
756
|
-
"title": "New post",
|
|
757
|
-
"attachments": [
|
|
758
|
-
{
|
|
759
|
-
"type": "image",
|
|
760
|
-
"image": {
|
|
761
|
-
"id": 3,
|
|
762
|
-
"name": "logo",
|
|
763
|
-
"url": "http://images.com/logo.jpg"
|
|
764
|
-
}
|
|
765
|
-
},
|
|
766
|
-
{
|
|
767
|
-
"type": "video",
|
|
768
|
-
"video": {
|
|
769
|
-
"id": 12,
|
|
770
|
-
"uid": "XCSSMDFWW",
|
|
771
|
-
"source": "youtube"
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
]
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
```
|
|
778
|
-
|
|
779
|
-
When embedding ids:
|
|
780
|
-
|
|
781
|
-
```ruby
|
|
782
|
-
class PostSerializer < ActiveModel::Serializer
|
|
783
|
-
embed :ids
|
|
258
|
+
The `url` declaration describes which named routes to use while generating URLs
|
|
259
|
+
for your JSON. Not every adapter will require URLs.
|
|
784
260
|
|
|
785
|
-
|
|
786
|
-
has_many :attachments, polymorphic: true
|
|
787
|
-
end
|
|
788
|
-
```
|
|
261
|
+
## Caching
|
|
789
262
|
|
|
790
|
-
```
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
"title": "New post",
|
|
795
|
-
"attachment_ids": [
|
|
796
|
-
{
|
|
797
|
-
"type": "image",
|
|
798
|
-
"id": 12
|
|
799
|
-
},
|
|
800
|
-
{
|
|
801
|
-
"type": "video",
|
|
802
|
-
"id": 3
|
|
803
|
-
}
|
|
804
|
-
]
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
```
|
|
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}"```.
|
|
808
267
|
|
|
268
|
+
The cache support is optimized to use the cached object in multiple request. An object cached on an ```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.
|
|
809
269
|
|
|
810
|
-
|
|
270
|
+
**[NOTE] Every object is individually cached.**
|
|
811
271
|
|
|
812
|
-
|
|
813
|
-
provides to the serializer when you call `render :json`. By default, this is
|
|
814
|
-
`current_user`, but can be customized in your controller by calling
|
|
815
|
-
`serialization_scope`:
|
|
272
|
+
**[NOTE] The cache is automatically expired after update an object but it's not deleted.**
|
|
816
273
|
|
|
817
274
|
```ruby
|
|
818
|
-
|
|
819
|
-
serialization_scope :current_admin
|
|
820
|
-
end
|
|
275
|
+
cache(options = nil) # options: ```{key, expires_in, compress, force, race_condition_ttl}```
|
|
821
276
|
```
|
|
822
277
|
|
|
823
|
-
|
|
824
|
-
`current_admin`.
|
|
825
|
-
|
|
826
|
-
Please note that, until now, `serialization_scope` doesn't accept a second
|
|
827
|
-
object with options for specifying which actions should or should not take a
|
|
828
|
-
given scope in consideration.
|
|
829
|
-
|
|
830
|
-
To be clear, it's not possible, yet, to do something like this:
|
|
278
|
+
Take the example bellow:
|
|
831
279
|
|
|
832
280
|
```ruby
|
|
833
|
-
class
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
```
|
|
837
|
-
|
|
838
|
-
So, in order to have a fine grained control of what each action should take in
|
|
839
|
-
consideration for its scope, you may use something like this:
|
|
840
|
-
|
|
841
|
-
```ruby
|
|
842
|
-
class CitiesController < ApplicationController
|
|
843
|
-
serialization_scope nil
|
|
844
|
-
|
|
845
|
-
def index
|
|
846
|
-
@cities = City.all
|
|
847
|
-
|
|
848
|
-
render json: @cities, each_serializer: CitySerializer
|
|
849
|
-
end
|
|
281
|
+
class PostSerializer < ActiveModel::Serializer
|
|
282
|
+
cache key: 'post', expires_in: 3.hours
|
|
283
|
+
attributes :title, :body
|
|
850
284
|
|
|
851
|
-
|
|
852
|
-
@city = City.find(params[:id])
|
|
285
|
+
has_many :comments
|
|
853
286
|
|
|
854
|
-
|
|
855
|
-
end
|
|
287
|
+
url :post
|
|
856
288
|
end
|
|
857
289
|
```
|
|
858
290
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
that query, only the `show` action will.
|
|
863
|
-
|
|
864
|
-
## Testing
|
|
865
|
-
|
|
866
|
-
In order to test a Serializer, you can just call `.new` on it, passing the object to serialize:
|
|
867
|
-
|
|
868
|
-
### MiniTest
|
|
869
|
-
|
|
870
|
-
```ruby
|
|
871
|
-
class TestPostSerializer < Minitest::Test
|
|
872
|
-
def setup
|
|
873
|
-
@serializer = PostSerializer.new Post.new(id: 123, title: 'some title', body: 'some text')
|
|
874
|
-
end
|
|
875
|
-
|
|
876
|
-
def test_special_json_for_api
|
|
877
|
-
assert_equal '{"post":{"id":123,"title":"some title","body":"some text"}}', @serializer.to_json
|
|
878
|
-
end
|
|
879
|
-
```
|
|
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.
|
|
880
294
|
|
|
881
|
-
###
|
|
295
|
+
### Fragmenting Caching
|
|
882
296
|
|
|
883
|
-
|
|
884
|
-
describe PostSerializer do
|
|
885
|
-
it "creates special JSON for the API" do
|
|
886
|
-
serializer = PostSerializer.new Post.new(id: 123, title: 'some title', body: 'some text')
|
|
887
|
-
expect(serializer.to_json).to eql('{"post":{"id":123,"title":"some title","body":"some text"}}')
|
|
888
|
-
end
|
|
889
|
-
end
|
|
890
|
-
```
|
|
297
|
+
If there is some API endpoint that shouldn't be fully cached, you can still optmise it, using Fragment Cache on the attributes and relationships that you want to cache.
|
|
891
298
|
|
|
892
|
-
|
|
299
|
+
You can define the attribute by using ```only``` or ```except``` option on cache method.
|
|
893
300
|
|
|
894
|
-
NOTE
|
|
895
|
-
We need to re-think and re-design the caching strategy for the next
|
|
896
|
-
version of AMS.
|
|
301
|
+
**[NOTE] Cache serializers will be used at their relationships**
|
|
897
302
|
|
|
898
|
-
|
|
303
|
+
Example:
|
|
899
304
|
|
|
900
305
|
```ruby
|
|
901
306
|
class PostSerializer < ActiveModel::Serializer
|
|
902
|
-
|
|
903
|
-
|
|
307
|
+
cache key: 'post', expires_in: 3.hours, only: [:title]
|
|
904
308
|
attributes :title, :body
|
|
905
309
|
|
|
906
|
-
|
|
907
|
-
[object, scope]
|
|
908
|
-
end
|
|
909
|
-
end
|
|
910
|
-
```
|
|
911
|
-
|
|
912
|
-
The caching interface uses `Rails.cache` under the hood.
|
|
913
|
-
|
|
914
|
-
# ApplicationSerializer
|
|
915
|
-
|
|
916
|
-
By default, new serializers descend from ActiveModel::Serializer. However, if you wish to share behaviour across your serializers you can create an ApplicationSerializer at ```app/serializers/application_serializer.rb```:
|
|
310
|
+
has_many :comments
|
|
917
311
|
|
|
918
|
-
|
|
919
|
-
class ApplicationSerializer < ActiveModel::Serializer
|
|
312
|
+
url :post
|
|
920
313
|
end
|
|
921
314
|
```
|
|
922
315
|
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
```
|
|
926
|
-
$ rails g serializer post
|
|
927
|
-
```
|
|
928
|
-
|
|
929
|
-
now generates:
|
|
930
|
-
|
|
931
|
-
```ruby
|
|
932
|
-
class PostSerializer < ApplicationSerializer
|
|
933
|
-
attributes :id
|
|
934
|
-
end
|
|
935
|
-
```
|
|
316
|
+
## Getting Help
|
|
936
317
|
|
|
937
|
-
|
|
318
|
+
If you find a bug, please report an [Issue](https://github.com/rails-api/active_model_serializers/issues/new).
|
|
938
319
|
|
|
939
|
-
|
|
320
|
+
If you have a question, please [post to Stack Overflow](http://stackoverflow.com/questions/tagged/active-model-serializers).
|
|
940
321
|
|
|
941
|
-
|
|
942
|
-
trees, and it may be tempting to design in this way so that your client can make
|
|
943
|
-
fewer requests to get data and so that related querying can be optimized.
|
|
944
|
-
However, keeping things simple in your serializers and controllers may
|
|
945
|
-
significantly reduce complexity and maintenance over the long-term development
|
|
946
|
-
of your application. Please consider reducing the complexity of the JSON views
|
|
947
|
-
you provide via the serializers as you build out your application, so that
|
|
948
|
-
controllers/services can be more easily reused without a lot of complexity
|
|
949
|
-
later.
|
|
322
|
+
Thanks!
|
|
950
323
|
|
|
951
|
-
|
|
324
|
+
# Contributing
|
|
952
325
|
|
|
953
|
-
|
|
954
|
-
avoid n+1 queries by ensuring that data loads in an optimal fashion, e.g. if you
|
|
955
|
-
are using ActiveRecord, you might want to use query includes or joins as needed
|
|
956
|
-
to make the data available that the serializer(s) need.
|
|
326
|
+
See [CONTRIBUTING.md](https://github.com/rails-api/active_model_serializers/blob/master/CONTRIBUTING.md)
|