mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-22 22:06:50 +00:00
Compare commits
No commits in common. "v0.9.8" and "master" have entirely different histories.
29
.github/ISSUE_TEMPLATE.md
vendored
Normal file
29
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
#### Expected behavior vs actual behavior
|
||||
|
||||
|
||||
|
||||
#### Steps to reproduce
|
||||
*(e.g., detailed walkthrough, runnable script, example application)*
|
||||
|
||||
|
||||
|
||||
#### Environment
|
||||
|
||||
ActiveModelSerializers Version *(commit ref if not on tag)*:
|
||||
|
||||
Output of `ruby -e "puts RUBY_DESCRIPTION"`:
|
||||
|
||||
OS Type & Version:
|
||||
|
||||
Integrated application and version *(e.g., Rails, Grape, etc)*:
|
||||
|
||||
|
||||
#### Backtrace
|
||||
*(e.g., provide any applicable backtraces from your application)*
|
||||
|
||||
|
||||
|
||||
#### Additonal helpful information
|
||||
*(e.g., Gemfile.lock, configurations, PR containing a failing test, git bisect results)*
|
||||
|
||||
|
||||
15
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
15
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
#### Purpose
|
||||
|
||||
|
||||
#### Changes
|
||||
|
||||
|
||||
#### Caveats
|
||||
|
||||
|
||||
#### Related GitHub issues
|
||||
|
||||
|
||||
#### Additional helpful information
|
||||
|
||||
|
||||
17
.gitignore
vendored
17
.gitignore
vendored
@ -3,13 +3,16 @@
|
||||
.bundle
|
||||
.config
|
||||
.yardoc
|
||||
*.lock
|
||||
Gemfile.lock
|
||||
Gemfile.local
|
||||
InstalledFiles
|
||||
_yardoc
|
||||
coverage
|
||||
doc/
|
||||
lib/bundler/man
|
||||
pkg
|
||||
Vagrantfile
|
||||
.vagrant
|
||||
rdoc
|
||||
spec/reports
|
||||
test/tmp
|
||||
@ -17,4 +20,16 @@ test/version_tmp
|
||||
tmp
|
||||
*.swp
|
||||
.ruby-version
|
||||
.ruby-gemset
|
||||
vendor/bundle
|
||||
tags
|
||||
|
||||
# silly macs
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
Icon?
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
49
.travis.yml
49
.travis.yml
@ -2,54 +2,9 @@ language: ruby
|
||||
|
||||
sudo: false
|
||||
|
||||
rvm:
|
||||
- 1.9.3 # EOL
|
||||
- 2.0.0 # EOL
|
||||
- 2.1
|
||||
- ruby-head
|
||||
- jruby-9.1.5.0 # is precompiled per http://rubies.travis-ci.org/
|
||||
|
||||
jdk:
|
||||
- openjdk8
|
||||
|
||||
before_install:
|
||||
- gem update --system 2.6.8
|
||||
- if [ "$RUBY_VERSION" != "jruby-9.1.5.0" ] ; then update_rubygems ; fi
|
||||
- rvm @global do gem install bundler -v 1.13.7
|
||||
install: bundle _1.13.7_ install --path=vendor/bundle --retry=3 --jobs=3
|
||||
cache:
|
||||
directories:
|
||||
- vendor/bundle
|
||||
|
||||
env:
|
||||
global:
|
||||
- "JRUBY_OPTS='--dev -J-Xmx1024M --debug'"
|
||||
matrix:
|
||||
- "RAILS_VERSION=4.0"
|
||||
- "RAILS_VERSION=4.1"
|
||||
- "RAILS_VERSION=4.2"
|
||||
- "RAILS_VERSION=5.0"
|
||||
- "RAILS_VERSION=master"
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
- rvm: 1.9.3
|
||||
env: RAILS_VERSION=master
|
||||
- rvm: 2.0.0
|
||||
env: RAILS_VERSION=master
|
||||
- rvm: 2.1
|
||||
env: RAILS_VERSION=master
|
||||
- rvm: jruby-9.1.5.0
|
||||
env: RAILS_VERSION=master
|
||||
- rvm: 1.9.3
|
||||
env: RAILS_VERSION=5.0
|
||||
- rvm: 2.0.0
|
||||
env: RAILS_VERSION=5.0
|
||||
- rvm: 2.1
|
||||
env: RAILS_VERSION=5.0
|
||||
- rvm: jruby-9.1.5.0
|
||||
env: RAILS_VERSION=5.0
|
||||
allow_failures:
|
||||
- rvm: ruby-head
|
||||
- env: "RAILS_VERSION=master"
|
||||
fast_finish: true
|
||||
script:
|
||||
- true
|
||||
|
||||
92
CHANGELOG-0-08.md
Normal file
92
CHANGELOG-0-08.md
Normal file
@ -0,0 +1,92 @@
|
||||
## 0.08.x
|
||||
|
||||
### v0.8.3 (2014/12/10 14:45 +00:00)
|
||||
- [#753](https://github.com/rails-api/active_model_serializers/pull/753) Test against Ruby 2.2 on Travis CI (@tricknotes)
|
||||
- [#745](https://github.com/rails-api/active_model_serializers/pull/745) Missing a word (@jockee)
|
||||
|
||||
### v0.8.2 (2014/09/01 21:00 +00:00)
|
||||
- [#612](https://github.com/rails-api/active_model_serializers/pull/612) Feature/adapter (@bolshakov)
|
||||
* adds adapters pattern
|
||||
- [#615](https://github.com/rails-api/active_model_serializers/pull/615) Rails does not support const_defined? in development mode (@tpitale)
|
||||
- [#613](https://github.com/rails-api/active_model_serializers/pull/613) README: typo fix on attributes (@spk)
|
||||
- [#614](https://github.com/rails-api/active_model_serializers/pull/614) Fix rails 4.0.x build. (@arthurnn)
|
||||
- [#610](https://github.com/rails-api/active_model_serializers/pull/610) ArraySerializer (@bolshakov)
|
||||
- [#607](https://github.com/rails-api/active_model_serializers/pull/607) ruby syntax highlights (@zigomir)
|
||||
- [#602](https://github.com/rails-api/active_model_serializers/pull/602) Add DSL for associations (@JordanFaust)
|
||||
|
||||
### 0.8.1 (May 6, 2013)
|
||||
|
||||
* Fix bug whereby a serializer using 'options' would blow up.
|
||||
|
||||
### 0.8.0 (May 5, 2013)
|
||||
|
||||
* Attributes can now have optional types.
|
||||
|
||||
* A new DefaultSerializer ensures that POROs behave the same way as ActiveModels.
|
||||
|
||||
* If you wish to override ActiveRecord::Base#to_Json, you can now require
|
||||
'active_record/serializer_override'. We don't recommend you do this, but
|
||||
many users do, so we've left it optional.
|
||||
|
||||
* Fixed a bug where ActionController wouldn't always have MimeResponds.
|
||||
|
||||
* An optinal caching feature allows you to cache JSON & hashes that AMS uses.
|
||||
Adding 'cached true' to your Serializers will turn on this cache.
|
||||
|
||||
* URL helpers used inside of Engines now work properly.
|
||||
|
||||
* Serializers now can filter attributes with `only` and `except`:
|
||||
|
||||
```
|
||||
UserSerializer.new(user, only: [:first_name, :last_name])
|
||||
UserSerializer.new(user, except: :first_name)
|
||||
```
|
||||
|
||||
* Basic Mongoid support. We now include our mixins in the right place.
|
||||
|
||||
* On Ruby 1.8, we now generate an `id` method that properly serializes `id`
|
||||
columns. See issue #127 for more.
|
||||
|
||||
* Add an alias for `scope` method to be the name of the context. By default
|
||||
this is `current_user`. The name is automatically set when using
|
||||
`serialization_scope` in the controller.
|
||||
|
||||
* Pass through serialization options (such as `:include`) when a model
|
||||
has no serializer defined.
|
||||
|
||||
## [0.7.0 (March 6, 2013)](https://github.com/rails-api/active_model_serializers/commit/fabdc621ff97fbeca317f6301973dd4564b9e695)
|
||||
|
||||
* ```embed_key``` option to allow embedding by attributes other than IDs
|
||||
* Fix rendering nil with custom serializer
|
||||
* Fix global ```self.root = false```
|
||||
* Add support for specifying the serializer for an association as a String
|
||||
* Able to specify keys on the attributes method
|
||||
* Serializer Reloading via ActiveSupport::DescendantsTracker
|
||||
* Reduce double map to once; Fixes datamapper eager loading.
|
||||
|
||||
## 0.6.0 (October 22, 2012)
|
||||
|
||||
* Serialize sets properly
|
||||
* Add root option to ArraySerializer
|
||||
* Support polymorphic associations
|
||||
* Support :each_serializer in ArraySerializer
|
||||
* Add `scope` method to easily access the scope in the serializer
|
||||
* Fix regression with Rails 3.2.6; add Rails 4 support
|
||||
* Allow serialization_scope to be disabled with serialization_scope nil
|
||||
* Array serializer should support pure ruby objects besides serializers
|
||||
|
||||
## 0.05.x
|
||||
|
||||
### [0.5.2 (June 5, 2012)](https://github.com/rails-api/active_model_serializers/commit/615afd125c260432d456dc8be845867cf87ea118#diff-0c5c12f311d3b54734fff06069efd2ac)
|
||||
|
||||
### [0.5.1 (May 23, 2012)](https://github.com/rails-api/active_model_serializers/commit/00194ec0e41831802fcbf893a34c0bb0853ebe14#diff-0c5c12f311d3b54734fff06069efd2ac)
|
||||
|
||||
### [0.5.0 (May 16, 2012)](https://github.com/rails-api/active_model_serializers/commit/33d4842dcd35c7167b0b33fc0abcf00fb2c92286)
|
||||
|
||||
* First tagged version
|
||||
* Changes generators to always generate an ApplicationSerializer
|
||||
|
||||
## [0.1.0 (December 21, 2011)](https://github.com/rails-api/active_model_serializers/commit/1e0c9ef93b96c640381575dcd30be07ac946818b)
|
||||
|
||||
## First Commit as [Rails Serializers 0.0.1](https://github.com/rails-api/active_model_serializers/commit/d72b66d4c5355b0ff0a75a04895fcc4ea5b0c65e)
|
||||
(December 1, 2011).
|
||||
74
CHANGELOG-0-09.md
Normal file
74
CHANGELOG-0-09.md
Normal file
@ -0,0 +1,74 @@
|
||||
## 0.09.x
|
||||
|
||||
### v0.9.3 (2015/01/21 20:29 +00:00)
|
||||
|
||||
Features:
|
||||
- [#774](https://github.com/rails-api/active_model_serializers/pull/774) Fix nested include attributes (@nhocki)
|
||||
- [#771](https://github.com/rails-api/active_model_serializers/pull/771) Make linked resource type names consistent with root names (@sweatypitts)
|
||||
- [#696](https://github.com/rails-api/active_model_serializers/pull/696) Explicitly set serializer for associations (@ggordon)
|
||||
- [#700](https://github.com/rails-api/active_model_serializers/pull/700) sparse fieldsets (@arenoir)
|
||||
- [#768](https://github.com/rails-api/active_model_serializers/pull/768) Adds support for `meta` and `meta_key` attribute (@kurko)
|
||||
|
||||
### v0.9.1 (2014/12/04 11:54 +00:00)
|
||||
- [#707](https://github.com/rails-api/active_model_serializers/pull/707) A Friendly Note on Which AMS Version to Use (@jherdman)
|
||||
- [#730](https://github.com/rails-api/active_model_serializers/pull/730) Fixes nested has_many links in JSONAPI (@kurko)
|
||||
- [#718](https://github.com/rails-api/active_model_serializers/pull/718) Allow overriding the adapter with render option (@ggordon)
|
||||
- [#720](https://github.com/rails-api/active_model_serializers/pull/720) Rename attribute with :key (0.8.x compatibility) (@ggordon)
|
||||
- [#728](https://github.com/rails-api/active_model_serializers/pull/728) Use type as key for linked resources (@kurko)
|
||||
- [#729](https://github.com/rails-api/active_model_serializers/pull/729) Use the new beta build env on Travis (@joshk)
|
||||
- [#703](https://github.com/rails-api/active_model_serializers/pull/703) Support serializer and each_serializer options in renderer (@ggordon, @mieko)
|
||||
- [#727](https://github.com/rails-api/active_model_serializers/pull/727) Includes links inside of linked resources (@kurko)
|
||||
- [#726](https://github.com/rails-api/active_model_serializers/pull/726) Bugfix: include nested has_many associations (@kurko)
|
||||
- [#722](https://github.com/rails-api/active_model_serializers/pull/722) Fix infinite recursion (@ggordon)
|
||||
- [#1](https://github.com/rails-api/active_model_serializers/pull/1) Allow for the implicit use of ArraySerializer when :each_serializer is specified (@mieko)
|
||||
- [#692](https://github.com/rails-api/active_model_serializers/pull/692) Include 'linked' member for json-api collections (@ggordon)
|
||||
- [#714](https://github.com/rails-api/active_model_serializers/pull/714) Define as_json instead of to_json (@guilleiguaran)
|
||||
- [#710](https://github.com/rails-api/active_model_serializers/pull/710) JSON-API: Don't include linked section if associations are empty (@guilleiguaran)
|
||||
- [#711](https://github.com/rails-api/active_model_serializers/pull/711) Fixes rbx gems bundling on TravisCI (@kurko)
|
||||
- [#709](https://github.com/rails-api/active_model_serializers/pull/709) Add type key when association name is different than object type (@guilleiguaran)
|
||||
- [#708](https://github.com/rails-api/active_model_serializers/pull/708) Handle correctly null associations (@guilleiguaran)
|
||||
- [#691](https://github.com/rails-api/active_model_serializers/pull/691) Fix embed option for associations (@jacob-s-son)
|
||||
- [#689](https://github.com/rails-api/active_model_serializers/pull/689) Fix support for custom root in JSON-API adapter (@guilleiguaran)
|
||||
- [#685](https://github.com/rails-api/active_model_serializers/pull/685) Serialize ids as strings in JSON-API adapter (@guilleiguaran)
|
||||
- [#684](https://github.com/rails-api/active_model_serializers/pull/684) Refactor adapters to implement support for array serialization (@guilleiguaran)
|
||||
- [#682](https://github.com/rails-api/active_model_serializers/pull/682) Include root by default in JSON-API serializers (@guilleiguaran)
|
||||
- [#625](https://github.com/rails-api/active_model_serializers/pull/625) Add DSL for urls (@JordanFaust)
|
||||
- [#677](https://github.com/rails-api/active_model_serializers/pull/677) Add support for embed: :ids option for in associations (@guilleiguaran)
|
||||
- [#681](https://github.com/rails-api/active_model_serializers/pull/681) Check superclasses for Serializers (@quainjn)
|
||||
- [#680](https://github.com/rails-api/active_model_serializers/pull/680) Add support for root keys (@NullVoxPopuli)
|
||||
- [#675](https://github.com/rails-api/active_model_serializers/pull/675) Support Rails 4.2.0 (@tricknotes)
|
||||
- [#667](https://github.com/rails-api/active_model_serializers/pull/667) Require only activemodel instead of full rails (@guilleiguaran)
|
||||
- [#653](https://github.com/rails-api/active_model_serializers/pull/653) Add "_test" suffix to JsonApi::HasManyTest filename. (@alexgenco)
|
||||
- [#631](https://github.com/rails-api/active_model_serializers/pull/631) Update build badge URL (@craiglittle)
|
||||
|
||||
### 0.9.0.alpha1 - January 7, 2014
|
||||
|
||||
### 0.9.0.pre
|
||||
|
||||
* The following methods were removed
|
||||
- Model#active\_model\_serializer
|
||||
- Serializer#include!
|
||||
- Serializer#include?
|
||||
- Serializer#attr\_disabled=
|
||||
- Serializer#cache
|
||||
- Serializer#perform\_caching
|
||||
- Serializer#schema (needs more discussion)
|
||||
- Serializer#attribute
|
||||
- Serializer#include\_#{name}? (filter method added)
|
||||
- Serializer#attributes (took a hash)
|
||||
|
||||
* The following things were added
|
||||
- Serializer#filter method
|
||||
- CONFIG object
|
||||
|
||||
* Remove support for ruby 1.8 versions.
|
||||
|
||||
* Require rails >= 3.2.
|
||||
|
||||
* Serializers for associations are being looked up in a parent serializer's namespace first. Same with controllers' namespaces.
|
||||
|
||||
* Added a "prefix" option in case you want to use a different version of serializer.
|
||||
|
||||
* Serializers default namespace can be set in `default_serializer_options` and inherited by associations.
|
||||
|
||||
* [Beginning of rewrite: c65d387705ec534db171712671ba7fcda4f49f68](https://github.com/rails-api/active_model_serializers/commit/c65d387705ec534db171712671ba7fcda4f49f68)
|
||||
466
CHANGELOG-0-10.md
Normal file
466
CHANGELOG-0-10.md
Normal file
@ -0,0 +1,466 @@
|
||||
## 0.10.x
|
||||
|
||||
### [0-10-stable (unreleased)](https://github.com/rails-api/active_model_serializers/compare/v0.10.6...0-10-stable)
|
||||
|
||||
Breaking changes:
|
||||
|
||||
Features:
|
||||
|
||||
Fixes:
|
||||
|
||||
Misc:
|
||||
|
||||
### [v0.10.6 (2017-05-01)](https://github.com/rails-api/active_model_serializers/compare/v0.10.5...v0.10.6)
|
||||
|
||||
Fixes:
|
||||
|
||||
- [#1857](https://github.com/rails-api/active_model_serializers/pull/1857) JSON:API does not load belongs_to relation to get identifier id. (@bf4)
|
||||
- [#2119](https://github.com/rails-api/active_model_serializers/pull/2119) JSON:API returns null resource object identifier when 'id' is null. (@bf4)
|
||||
- [#2093](https://github.com/rails-api/active_model_serializers/pull/2093) undef problematic Serializer methods: display, select. (@bf4)
|
||||
|
||||
Misc:
|
||||
|
||||
- [#2104](https://github.com/rails-api/active_model_serializers/pull/2104) Documentation for serializers and rendering. (@cassidycodes)
|
||||
- [#2081](https://github.com/rails-api/active_model_serializers/pull/2081) Documentation for `include` option in adapters. (@charlie-wasp)
|
||||
- [#2120](https://github.com/rails-api/active_model_serializers/pull/2120) Documentation for association options: foreign_key, type, class_name, namespace. (@bf4)
|
||||
|
||||
### [v0.10.5 (2017-03-07)](https://github.com/rails-api/active_model_serializers/compare/v0.10.4...v0.10.5)
|
||||
|
||||
Breaking changes:
|
||||
|
||||
Features:
|
||||
|
||||
- [#2021](https://github.com/rails-api/active_model_serializers/pull/2021) ActiveModelSerializers::Model#attributes. Originally in [#1982](https://github.com/rails-api/active_model_serializers/pull/1982). (@bf4)
|
||||
- [#2057](https://github.com/rails-api/active_model_serializers/pull/2057)
|
||||
Update version constraint for jsonapi-renderer to `['>= 0.1.1.beta1', '< 0.2']`
|
||||
(@jaredbeck)
|
||||
|
||||
Fixes:
|
||||
|
||||
- [#2022](https://github.com/rails-api/active_model_serializers/pull/2022) Mutation of ActiveModelSerializers::Model now changes the attributes. Originally in [#1984](https://github.com/rails-api/active_model_serializers/pull/1984). (@bf4)
|
||||
|
||||
Misc:
|
||||
|
||||
- [#2055](https://github.com/rails-api/active_model_serializers/pull/2055)
|
||||
Replace deprecated dependency jsonapi with jsonapi-renderer. (@jaredbeck)
|
||||
- [#2021](https://github.com/rails-api/active_model_serializers/pull/2021) Make test attributes explicit. Tests have Model#associations. (@bf4)
|
||||
- [#1981](https://github.com/rails-api/active_model_serializers/pull/1981) Fix relationship link documentation. (@groyoh)
|
||||
- [#2035](https://github.com/rails-api/active_model_serializers/pull/2035) Document how to disable the logger. (@MSathieu)
|
||||
- [#2039](https://github.com/rails-api/active_model_serializers/pull/2039) Documentation fixes. (@biow0lf)
|
||||
|
||||
### [v0.10.4 (2017-01-06)](https://github.com/rails-api/active_model_serializers/compare/v0.10.3...v0.10.4)
|
||||
|
||||
Misc:
|
||||
|
||||
- [#2005](https://github.com/rails-api/active_model_serializers/pull/2005) Update jsonapi runtime dependency to 0.1.1.beta6, support Ruby 2.4. (@kofronpi)
|
||||
- [#1993](https://github.com/rails-api/active_model_serializers/pull/1993) Swap out KeyTransform for CaseTransform gem for the possibility of native extension use. (@NullVoxPopuli)
|
||||
|
||||
### [v0.10.3 (2016-11-21)](https://github.com/rails-api/active_model_serializers/compare/v0.10.2...v0.10.3)
|
||||
|
||||
Fixes:
|
||||
|
||||
- [#1973](https://github.com/rails-api/active_model_serializers/pull/1973) Fix namespace lookup for collections and has_many relationships (@groyoh)
|
||||
- [#1887](https://github.com/rails-api/active_model_serializers/pull/1887) Make the comment reflect what the function does (@johnnymo87)
|
||||
- [#1890](https://github.com/rails-api/active_model_serializers/issues/1890) Ensure generator inherits from ApplicationSerializer when available (@richmolj)
|
||||
- [#1922](https://github.com/rails-api/active_model_serializers/pull/1922) Make railtie an optional dependency in runtime (@ggpasqualino)
|
||||
- [#1930](https://github.com/rails-api/active_model_serializers/pull/1930) Ensure valid jsonapi when relationship has no links or data (@richmolj)
|
||||
|
||||
Features:
|
||||
|
||||
- [#1757](https://github.com/rails-api/active_model_serializers/pull/1757) Make serializer lookup chain configurable. (@NullVoxPopuli)
|
||||
- [#1968](https://github.com/rails-api/active_model_serializers/pull/1968) (@NullVoxPopuli)
|
||||
- Add controller namespace to default controller lookup
|
||||
- Provide a `namespace` render option
|
||||
- document how set the namespace in the controller for implicit lookup.
|
||||
- [#1791](https://github.com/rails-api/active_model_serializers/pull/1791) (@bf4, @youroff, @NullVoxPopuli)
|
||||
- Added `jsonapi_namespace_separator` config option.
|
||||
- [#1889](https://github.com/rails-api/active_model_serializers/pull/1889) Support key transformation for Attributes adapter (@iancanderson, @danbee)
|
||||
- [#1917](https://github.com/rails-api/active_model_serializers/pull/1917) Add `jsonapi_pagination_links_enabled` configuration option (@richmolj)
|
||||
- [#1797](https://github.com/rails-api/active_model_serializers/pull/1797) Only include 'relationships' when sideloading (@richmolj)
|
||||
|
||||
Fixes:
|
||||
|
||||
- [#1833](https://github.com/rails-api/active_model_serializers/pull/1833) Remove relationship links if they are null (@groyoh)
|
||||
- [#1881](https://github.com/rails-api/active_model_serializers/pull/1881) ActiveModelSerializers::Model correctly works with string keys (@yevhene)
|
||||
|
||||
Misc:
|
||||
- [#1767](https://github.com/rails-api/active_model_serializers/pull/1767) Replace raising/rescuing `CollectionSerializer::NoSerializerError`,
|
||||
throw/catch `:no_serializer`. (@bf4)
|
||||
- [#1839](https://github.com/rails-api/active_model_serializers/pull/1839) `fields` tests demonstrating usage for both attributes and relationships. (@NullVoxPopuli)
|
||||
- [#1812](https://github.com/rails-api/active_model_serializers/pull/1812) add a code of conduct (@corainchicago)
|
||||
|
||||
- [#1878](https://github.com/rails-api/active_model_serializers/pull/1878) Cache key generation for serializers now uses `ActiveSupport::Cache.expand_cache_key` instead of `Array#join` by default and is also overridable. This change should be backward-compatible. (@markiz)
|
||||
|
||||
- [#1799](https://github.com/rails-api/active_model_serializers/pull/1799) Add documentation for setting the adapter. (@cassidycodes)
|
||||
- [#1909](https://github.com/rails-api/active_model_serializers/pull/1909) Add documentation for relationship links. (@vasilakisfil, @NullVoxPopuli)
|
||||
- [#1959](https://github.com/rails-api/active_model_serializers/pull/1959) Add documentation for root. (@shunsuke227ono)
|
||||
- [#1967](https://github.com/rails-api/active_model_serializers/pull/1967) Improve type method documentation. (@yukideluxe)
|
||||
|
||||
### [v0.10.2 (2016-07-05)](https://github.com/rails-api/active_model_serializers/compare/v0.10.1...v0.10.2)
|
||||
|
||||
Fixes:
|
||||
- [#1814](https://github.com/rails-api/active_model_serializers/pull/1814) Ensuring read_multi works with fragment cache
|
||||
- [#1848](https://github.com/rails-api/active_model_serializers/pull/1848) Redefine associations on inherited serializers. (@EhsanYousefi)
|
||||
|
||||
Misc:
|
||||
- [#1808](https://github.com/rails-api/active_model_serializers/pull/1808) Adds documentation for `fields` option. (@luizkowalski)
|
||||
|
||||
### [v0.10.1 (2016-06-16)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0...v0.10.1)
|
||||
|
||||
Features:
|
||||
- [#1668](https://github.com/rails-api/active_model_serializers/pull/1668) Exclude nil and empty links. (@sigmike)
|
||||
- [#1426](https://github.com/rails-api/active_model_serializers/pull/1426) Add ActiveModelSerializers.config.default_includes (@empact)
|
||||
|
||||
Fixes:
|
||||
- [#1754](https://github.com/rails-api/active_model_serializers/pull/1754) Fixes #1759, Grape integration, improves serialization_context
|
||||
missing error message on pagination. Document overriding CollectionSerializer#paginated?. (@bf4)
|
||||
Moved serialization_context creation to Grape formatter, so resource serialization works without explicit calls to the `render` helper method.
|
||||
Added Grape collection tests. (@onomated)
|
||||
- [#1287](https://github.com/rails-api/active_model_serializers/pull/1287) Pass `fields` options from adapter to serializer. (@vasilakisfil)
|
||||
- [#1710](https://github.com/rails-api/active_model_serializers/pull/1710) Prevent association loading when `include_data` option
|
||||
is set to `false`. (@groyoh)
|
||||
- [#1747](https://github.com/rails-api/active_model_serializers/pull/1747) Improve jsonapi mime type registration for Rails 5 (@remear)
|
||||
|
||||
Misc:
|
||||
- [#1734](https://github.com/rails-api/active_model_serializers/pull/1734) Adds documentation for conditional attribute (@lambda2)
|
||||
- [#1685](https://github.com/rails-api/active_model_serializers/pull/1685) Replace `IncludeTree` with `IncludeDirective` from the jsonapi gem.
|
||||
|
||||
### [v0.10.0 (2016-05-17)](https://github.com/rails-api/active_model_serializers/compare/4a2d9853ba7...v0.10.0)
|
||||
|
||||
Breaking changes:
|
||||
- [#1662](https://github.com/rails-api/active_model_serializers/pull/1662) Drop support for Rails 4.0 and Ruby 2.0.0. (@remear)
|
||||
|
||||
Features:
|
||||
- [#1677](https://github.com/rails-api/active_model_serializers/pull/1677) Add `assert_schema`, `assert_request_schema`, `assert_request_response_schema`. (@bf4)
|
||||
- [#1697](https://github.com/rails-api/active_model_serializers/pull/1697) Include actual exception message with custom exceptions;
|
||||
`Test::Schema` exceptions are now `Minitest::Assertion`s. (@bf4)
|
||||
- [#1699](https://github.com/rails-api/active_model_serializers/pull/1699) String/Lambda support for conditional attributes/associations (@mtsmfm)
|
||||
- [#1687](https://github.com/rails-api/active_model_serializers/pull/1687) Only calculate `_cache_digest` (in `cache_key`) when `skip_digest` is false. (@bf4)
|
||||
- [#1647](https://github.com/rails-api/active_model_serializers/pull/1647) Restrict usage of `serializable_hash` options
|
||||
to the ActiveModel::Serialization and ActiveModel::Serializers::JSON interface. (@bf4)
|
||||
|
||||
Fixes:
|
||||
- [#1700](https://github.com/rails-api/active_model_serializers/pull/1700) Support pagination link for Kaminari when no data is returned. (@iamnader)
|
||||
- [#1726](https://github.com/rails-api/active_model_serializers/pull/1726) Adds polymorphic option to association definition which includes association type/nesting in serializer (@cgmckeever)
|
||||
|
||||
Misc:
|
||||
- [#1673](https://github.com/rails-api/active_model_serializers/pull/1673) Adds "How to" guide on using AMS with POROs (@DrSayre)
|
||||
- [#1730](https://github.com/rails-api/active_model_serializers/pull/1730) Adds documentation for overriding default serializer based on conditions (@groyoh/@cgmckeever)
|
||||
|
||||
### [v0.10.0.rc5 (2016-04-04)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0.rc4...v0.10.0.rc5)
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- [#1645](https://github.com/rails-api/active_model_serializers/pull/1645) Changed :dashed key transform to :dash. (@remear)
|
||||
- [#1574](https://github.com/rails-api/active_model_serializers/pull/1574) Default key case for the JsonApi adapter changed to dashed. (@remear)
|
||||
|
||||
Features:
|
||||
- [#1645](https://github.com/rails-api/active_model_serializers/pull/1645) Transform keys referenced in values. (@remear)
|
||||
- [#1650](https://github.com/rails-api/active_model_serializers/pull/1650) Fix serialization scope options `scope`, `scope_name`
|
||||
take precedence over `serialization_scope` in the controller.
|
||||
Fix tests that required tearing down dynamic methods. (@bf4)
|
||||
- [#1644](https://github.com/rails-api/active_model_serializers/pull/1644) Include adapter name in cache key so
|
||||
that the same serializer can be cached per adapter. (@bf4 via #1346 by @kevintyll)
|
||||
- [#1642](https://github.com/rails-api/active_model_serializers/pull/1642) Prefer object.cache_key over the generated
|
||||
cache key. (@bf4 via #1346 by @kevintyll)
|
||||
- [#1637](https://github.com/rails-api/active_model_serializers/pull/1637) Make references to 'ActionController::Base.cache_store' explicit
|
||||
in order to avoid issues when application controllers inherit from 'ActionController::API'. (@ncuesta)
|
||||
- [#1633](https://github.com/rails-api/active_model_serializers/pull/1633) Yield 'serializer' to serializer association blocks. (@bf4)
|
||||
- [#1616](https://github.com/rails-api/active_model_serializers/pull/1616) SerializableResource handles no serializer like controller. (@bf4)
|
||||
- [#1618](https://github.com/rails-api/active_model_serializers/issues/1618) Get collection root key for
|
||||
empty collection from explicit serializer option, when possible. (@bf4)
|
||||
- [#1574](https://github.com/rails-api/active_model_serializers/pull/1574) Provide key translation. (@remear)
|
||||
- [#1494](https://github.com/rails-api/active_model_serializers/pull/1494) Make serializers serializalbe
|
||||
(using the Attributes adapter by default). (@bf4)
|
||||
- [#1550](https://github.com/rails-api/active_model_serializers/pull/1550) Add
|
||||
Rails url_helpers to `SerializationContext` for use in links. (@remear, @bf4)
|
||||
- [#1004](https://github.com/rails-api/active_model_serializers/pull/1004) JSON API errors object implementation.
|
||||
- Only implements `detail` and `source` as derived from `ActiveModel::Error`
|
||||
- Provides checklist of remaining questions and remaining parts of the spec.
|
||||
- [#1515](https://github.com/rails-api/active_model_serializers/pull/1515) Adds support for symbols to the
|
||||
`ActiveModel::Serializer.type` method. (@groyoh)
|
||||
- [#1504](https://github.com/rails-api/active_model_serializers/pull/1504) Adds the changes missing from #1454
|
||||
and add more tests for resource identifier and relationship objects. Fix association block with link
|
||||
returning `data: nil`.(@groyoh)
|
||||
- [#1372](https://github.com/rails-api/active_model_serializers/pull/1372) Support
|
||||
cache_store.read_multi. (@LcpMarvel)
|
||||
- [#1018](https://github.com/rails-api/active_model_serializers/pull/1018) Add more tests and docs for top-level links. (@leandrocp)
|
||||
- [#1454](https://github.com/rails-api/active_model_serializers/pull/1454) Add support for
|
||||
relationship-level links and meta attributes. (@beauby)
|
||||
- [#1340](https://github.com/rails-api/active_model_serializers/pull/1340) Add support for resource-level meta. (@beauby)
|
||||
|
||||
Fixes:
|
||||
- [#1657](https://github.com/rails-api/active_model_serializers/pull/1657) Add missing missing require "active_support/json". (@andreaseger)
|
||||
- [#1661](https://github.com/rails-api/active_model_serializers/pull/1661) Fixes `read_attribute_for_serialization` not
|
||||
seeing methods defined in serialization superclass (#1653, #1658, #1660), introduced in #1650. (@bf4)
|
||||
- [#1651](https://github.com/rails-api/active_model_serializers/pull/1651) Fix deserialization of nil relationships. (@NullVoxPopuli)
|
||||
- [#1480](https://github.com/rails-api/active_model_serializers/pull/1480) Fix setting of cache_store from Rails configuration. (@bf4)
|
||||
Fix unintentional mutating of value in memory cache store. (@groyoh)
|
||||
- [#1622](https://github.com/rails-api/active_model_serializers/pull/1622) Fragment cache changed from per-record to per-serializer.
|
||||
Now, two serializers that use the same model may be separately cached. (@lserman)
|
||||
- [#1478](https://github.com/rails-api/active_model_serializers/pull/1478) Cache store will now be correctly set when serializers are
|
||||
loaded *before* Rails initializes. (@bf4)
|
||||
- [#1570](https://github.com/rails-api/active_model_serializers/pull/1570) Fixed pagination issue with last page size. (@bmorrall)
|
||||
- [#1516](https://github.com/rails-api/active_model_serializers/pull/1516) No longer return a nil href when only
|
||||
adding meta to a relationship link. (@groyoh)
|
||||
- [#1458](https://github.com/rails-api/active_model_serializers/pull/1458) Preserve the serializer
|
||||
type when fragment caching. (@bdmac)
|
||||
- [#1477](https://github.com/rails-api/active_model_serializers/pull/1477) Fix `fragment_cached?`
|
||||
method to check if caching. (@bdmac)
|
||||
- [#1501](https://github.com/rails-api/active_model_serializers/pull/1501) Adds tests for SerializableResource::use_adapter?,doc typos (@domitian)
|
||||
- [#1488](https://github.com/rails-api/active_model_serializers/pull/1488) Require ActiveSupport's string inflections (@nate00)
|
||||
|
||||
Misc:
|
||||
- [#1608](https://github.com/rails-api/active_model_serializers/pull/1608) Move SerializableResource to ActiveModelSerializers (@groyoh)
|
||||
- [#1602](https://github.com/rails-api/active_model_serializers/pull/1602) Add output examples to Adapters docs (@remear)
|
||||
- [#1557](https://github.com/rails-api/active_model_serializers/pull/1557) Update docs regarding overriding the root key (@Jwan622)
|
||||
- [#1471](https://github.com/rails-api/active_model_serializers/pull/1471) [Cleanup] Serializer caching is its own concern. (@bf4)
|
||||
- [#1482](https://github.com/rails-api/active_model_serializers/pull/1482) Document JSON API implementation defs and progress in class. (@bf4)
|
||||
- [#1551](https://github.com/rails-api/active_model_serializers/pull/1551) Added codebeat badge (@korzonek)
|
||||
- [#1527](https://github.com/rails-api/active_model_serializers/pull/1527) Refactor fragment cache class. (@groyoh)
|
||||
- [#1560](https://github.com/rails-api/active_model_serializers/pull/1560) Update rubocop and address its warnings. (@bf4 @groyoh)
|
||||
- [#1545](https://github.com/rails-api/active_model_serializers/pull/1545) Document how to pass arbitrary options to the
|
||||
serializer (@CodedBeardedSignedTaylor)
|
||||
- [#1496](https://github.com/rails-api/active_model_serializers/pull/1496) Run all branches against JRuby on CI (@nadavshatz)
|
||||
- [#1559](https://github.com/rails-api/active_model_serializers/pull/1559) Add a deprecation DSL. (@bf4 @groyoh)
|
||||
- [#1543](https://github.com/rails-api/active_model_serializers/pull/1543) Add the changes missing from #1535. (@groyoh)
|
||||
- [#1535](https://github.com/rails-api/active_model_serializers/pull/1535) Move the adapter and adapter folder to
|
||||
active_model_serializers folder and changes the module namespace. (@domitian @bf4)
|
||||
- [#1497](https://github.com/rails-api/active_model_serializers/pull/1497) Add JRuby-9000 to appveyor.yml(@corainchicago)
|
||||
- [#1420](https://github.com/rails-api/active_model_serializers/pull/1420) Adds tests and documentation for polymorphism(@marcgarreau)
|
||||
|
||||
|
||||
### [v0.10.0.rc4 (2016-01-27)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0.rc3...v0.10.0.rc4)
|
||||
Breaking changes:
|
||||
|
||||
- [#1360](https://github.com/rails-api/active_model_serializers/pull/1360)
|
||||
[#1369](https://github.com/rails-api/active_model_serializers/pull/1369) Drop support for Ruby 1.9.3 (@karaAJC, @maurogeorge)
|
||||
- [#1131](https://github.com/rails-api/active_model_serializers/pull/1131) Remove Serializer#root_name (@beauby)
|
||||
- [#1138](https://github.com/rails-api/active_model_serializers/pull/1138) Introduce Adapter::Base (@bf4)
|
||||
* Adapters now inherit Adapter::Base. 'Adapter' is now a module, no longer a class.
|
||||
* using a class as a namespace that you also inherit from is complicated and circular at times i.e.
|
||||
buggy (see https://github.com/rails-api/active_model_serializers/pull/1177)
|
||||
* The class methods on Adapter aren't necessarily related to the instance methods, they're more
|
||||
Adapter functions.
|
||||
* named `Base` because it's a Rails-ism.
|
||||
* It helps to isolate and highlight what the Adapter interface actually is.
|
||||
- [#1418](https://github.com/rails-api/active_model_serializers/pull/1418)
|
||||
serialized collections now use the root option as is; now, only the
|
||||
root derived from the serializer or object is always pluralized.
|
||||
|
||||
Features:
|
||||
|
||||
- [#1406](https://github.com/rails-api/active_model_serializers/pull/1406) Allow for custom dynamic values in JSON API links (@beauby)
|
||||
- [#1270](https://github.com/rails-api/active_model_serializers/pull/1270) Adds `assert_response_schema` test helper (@maurogeorge)
|
||||
- [#1099](https://github.com/rails-api/active_model_serializers/pull/1099) Adds `assert_serializer` test helper (@maurogeorge)
|
||||
- [#1403](https://github.com/rails-api/active_model_serializers/pull/1403) Add support for if/unless on attributes/associations (@beauby)
|
||||
- [#1248](https://github.com/rails-api/active_model_serializers/pull/1248) Experimental: Add support for JSON API deserialization (@beauby)
|
||||
- [#1378](https://github.com/rails-api/active_model_serializers/pull/1378) Change association blocks
|
||||
to be evaluated in *serializer* scope, rather than *association* scope. (@bf4)
|
||||
* Syntax changes from e.g.
|
||||
`has_many :titles do customers.pluck(:title) end` (in #1356) to
|
||||
`has_many :titles do object.customers.pluck(:title) end`
|
||||
- [#1356](https://github.com/rails-api/active_model_serializers/pull/1356) Add inline syntax for
|
||||
attributes and associations (@bf4 @beauby @noahsilas)
|
||||
* Allows defining attributes so that they don't conflict with existing methods. e.g. `attribute
|
||||
:title do 'Mr. Topum Hat' end`
|
||||
* Allows defining associations so that they don't conflict with existing methods. e.g. `has_many
|
||||
:titles do customers.pluck(:title) end`
|
||||
* Allows dynamic associations, as compared to compare to using
|
||||
[`virtual_value`](https://github.com/rails-api/active_model_serializers/pull/1356#discussion_r47146466).
|
||||
e.g. `has_many :reviews, virtual_value: [{ id: 1 }, { id: 2 }]`
|
||||
* Removes dynamically defined methods on the serializer
|
||||
- [#1336](https://github.com/rails-api/active_model_serializers/pull/1336) Added support for Grape >= 0.13, < 1.0 (@johnhamelink)
|
||||
- [#1322](https://github.com/rails-api/active_model_serializers/pull/1322) Instrumenting rendering of resources (@bf4, @maurogeorge)
|
||||
- [#1291](https://github.com/rails-api/active_model_serializers/pull/1291) Add logging (@maurogeorge)
|
||||
- [#1272](https://github.com/rails-api/active_model_serializers/pull/1272) Add PORO serializable base class: ActiveModelSerializers::Model (@bf4)
|
||||
- [#1255](https://github.com/rails-api/active_model_serializers/pull/1255) Make more class attributes inheritable (@bf4)
|
||||
- [#1249](https://github.com/rails-api/active_model_serializers/pull/1249) Inheritance of serializer inheriting the cache configuration(@Rodrigora)
|
||||
- [#1247](https://github.com/rails-api/active_model_serializers/pull/1247) Add support for toplevel JSON API links (@beauby)
|
||||
- [#1246](https://github.com/rails-api/active_model_serializers/pull/1246) Add support for resource-level JSON API links (@beauby)
|
||||
- [#1225](https://github.com/rails-api/active_model_serializers/pull/1225) Better serializer lookup, use nested serializer when it exists (@beauby)
|
||||
- [#1213](https://github.com/rails-api/active_model_serializers/pull/1213) `type` directive for serializer to control type field with json-api adapter (@youroff)
|
||||
- [#1172](https://github.com/rails-api/active_model_serializers/pull/1172) Better serializer registration, get more than just the first module (@bf4)
|
||||
- [#1158](https://github.com/rails-api/active_model_serializers/pull/1158) Add support for wildcards in `include` option (@beauby)
|
||||
- [#1127](https://github.com/rails-api/active_model_serializers/pull/1127) Add support for nested
|
||||
associations for JSON and Attributes adapters via the `include` option (@NullVoxPopuli, @beauby).
|
||||
- [#1050](https://github.com/rails-api/active_model_serializers/pull/1050) Add support for toplevel jsonapi member (@beauby, @bf4)
|
||||
- [#1251](https://github.com/rails-api/active_model_serializers/pull/1251) Rename ArraySerializer to
|
||||
CollectionSerializer for clarity, add ActiveModelSerializers.config.collection_serializer (@bf4)
|
||||
- [#1295](https://github.com/rails-api/active_model_serializers/pull/1295) Add config `serializer_lookup_enabled` that,
|
||||
when disabled, requires serializers to explicitly specified. (@trek)
|
||||
|
||||
Fixes:
|
||||
|
||||
- [#1352](https://github.com/rails-api/active_model_serializers/pull/1352) Fix generators; Isolate Rails-specifc code in Railties (@dgynn, @bf4)
|
||||
- [#1384](https://github.com/rails-api/active_model_serializers/pull/1384)Fix database state leaking across tests (@bf4)
|
||||
- [#1297](https://github.com/rails-api/active_model_serializers/pull/1297) Fix `fields` option to restrict relationships as well (@beauby)
|
||||
- [#1239](https://github.com/rails-api/active_model_serializers/pull/1239) Fix duplicates in JSON API compound documents (@beauby)
|
||||
- [#1214](https://github.com/rails-api/active_model_serializers/pull/1214) retrieve the key from the reflection options when building associations (@NullVoxPopuli, @hut8)
|
||||
- [#1358](https://github.com/rails-api/active_model_serializers/pull/1358) Handle serializer file paths with spaces (@rwstauner, @bf4)
|
||||
- [#1195](https://github.com/rails-api/active_model_serializers/pull/1195) Fix id override (@beauby)
|
||||
- [#1185](https://github.com/rails-api/active_model_serializers/pull/1185) Fix options passing in Json and Attributes adapters (@beauby)
|
||||
|
||||
Misc:
|
||||
|
||||
- [#1383](https://github.com/rails-api/active_model_serializers/pull/1383) Simplify reflections handling (@beauby)
|
||||
- [#1370](https://github.com/rails-api/active_model_serializers/pull/1370) Simplify attributes handling via a mixin (@beauby)
|
||||
- [#1301](https://github.com/rails-api/active_model_serializers/pull/1301) Mapping JSON API spec / schema to AMS (@bf4)
|
||||
- [#1271](https://github.com/rails-api/active_model_serializers/pull/1271) Handle no serializer source file to digest (@bf4)
|
||||
- [#1260](https://github.com/rails-api/active_model_serializers/pull/1260) Serialization and Cache Documentation (@bf4)
|
||||
- [#1259](https://github.com/rails-api/active_model_serializers/pull/1259) Add more info to CONTRIBUTING (@bf4)
|
||||
- [#1233](https://github.com/rails-api/active_model_serializers/pull/1233) Top-level meta and meta_key options no longer handled at serializer level (@beauby)
|
||||
- [#1232](https://github.com/rails-api/active_model_serializers/pull/1232) fields option no longer handled at serializer level (@beauby)
|
||||
- [#1220](https://github.com/rails-api/active_model_serializers/pull/1220) Remove empty rubocop.rake (@maurogeorge)
|
||||
- [#1178](https://github.com/rails-api/active_model_serializers/pull/1178) env CAPTURE_STDERR=false lets devs see hard failures (@bf4)
|
||||
- [#1177](https://github.com/rails-api/active_model_serializers/pull/1177) Remove Adapter autoloads in favor of require (@bf4)
|
||||
- [#1117](https://github.com/rails-api/active_model_serializers/pull/1117) FlattenJson adapter no longer inherits Json adapter, renamed to Attributes (@bf4)
|
||||
- [#1171](https://github.com/rails-api/active_model_serializers/pull/1171) add require statements to top of file (@shicholas)
|
||||
- [#1167](https://github.com/rails-api/active_model_serializers/pull/1167) Delegate Serializer.attributes to Serializer.attribute (@bf4)
|
||||
- [#1174](https://github.com/rails-api/active_model_serializers/pull/1174) Consistently refer to the 'JSON API' and the 'JsonApi' adapter (@bf4)
|
||||
- [#1173](https://github.com/rails-api/active_model_serializers/pull/1173) Comment private accessor warnings (@bf4)
|
||||
- [#1166](https://github.com/rails-api/active_model_serializers/pull/1166) Prefer methods over instance variables (@bf4)
|
||||
- [#1168](https://github.com/rails-api/active_model_serializers/pull/1168) Fix appveyor failure cache not being expired (@bf4)
|
||||
- [#1161](https://github.com/rails-api/active_model_serializers/pull/1161) Remove duplicate test helper (@bf4)
|
||||
- [#1360](https://github.com/rails-api/active_model_serializers/pull/1360) Update CI to test 2.2.2 -> 2.2.3 (@karaAJC)
|
||||
- [#1371](https://github.com/rails-api/active_model_serializers/pull/1371) Refactor, update, create documentation (@bf4)
|
||||
|
||||
### [v0.10.0.rc3 (2015-09-16)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0.rc2...v0.10.0.rc3)
|
||||
- [#1129](https://github.com/rails-api/active_model_serializers/pull/1129) Remove SerializableResource.serialize in favor of `.new` (@bf4)
|
||||
- [#1155](https://github.com/rails-api/active_model_serializers/pull/1155) Outside controller use tutorial (@CodedBeardedSignedTaylor)
|
||||
- [#1154](https://github.com/rails-api/active_model_serializers/pull/1154) Rubocop fixes for issues introduced by #1089 (@NullVoxPopuli)
|
||||
- [#1089](https://github.com/rails-api/active_model_serializers/pull/1089) Add ActiveModelSerializers.logger with default null device (@bf4)
|
||||
- [#1109](https://github.com/rails-api/active_model_serializers/pull/1109) Make better use of Minitest's lifecycle (@bf4)
|
||||
- [#1144](https://github.com/rails-api/active_model_serializers/pull/1144) Fix Markdown to adapters documentation (@bacarini)
|
||||
- [#1121](https://github.com/rails-api/active_model_serializers/pull/1121) Refactor `add_links` in JSONAPI adapter. (@beauby)
|
||||
- [#1150](https://github.com/rails-api/active_model_serializers/pull/1150) Remove legacy method accidentally reintroduced in #1017 (@beauby)
|
||||
- [#1149](https://github.com/rails-api/active_model_serializers/pull/1149) Update README with nested included association example. (@mattmueller)
|
||||
- [#1110](https://github.com/rails-api/active_model_serializers/pull/1110) Add lint tests for AR models (@beauby)
|
||||
- [#1131](https://github.com/rails-api/active_model_serializers/pull/1131) Extended format for JSONAPI `include` option (@beauby)
|
||||
* adds extended format for `include` option to JsonApi adapter
|
||||
- [#1142](https://github.com/rails-api/active_model_serializers/pull/1142) Updating wording on cache expiry in README (@leighhalliday)
|
||||
- [#1140](https://github.com/rails-api/active_model_serializers/pull/1140) Fix typo in fieldset exception (@lautis)
|
||||
- [#1132](https://github.com/rails-api/active_model_serializers/pull/1132) Get rid of unnecessary instance variables, and implied dependencies. (@beauby)
|
||||
- [#1139](https://github.com/rails-api/active_model_serializers/pull/1139) Documentation for serializing resources without render (@PericlesTheo)
|
||||
- [#1017](https://github.com/rails-api/active_model_serializers/pull/1017) Make Adapters registerable so they are not namespace-constrained (@bf4)
|
||||
- [#1120](https://github.com/rails-api/active_model_serializers/pull/1120) Add windows platform to loading sqlite3 (@Eric-Guo)
|
||||
- [#1123](https://github.com/rails-api/active_model_serializers/pull/1123) Remove url options (@bacarini)
|
||||
- [#1093](https://github.com/rails-api/active_model_serializers/pull/1093) Factor `with_adapter` + force cache clear before each test. (@beauby)
|
||||
- [#1095](https://github.com/rails-api/active_model_serializers/pull/1095) Add documentation about configuration options. (@beauby)
|
||||
- [#1069](https://github.com/rails-api/active_model_serializers/pull/1069) Add test coverage; account for no artifacts on CI (@bf4)
|
||||
- [#1103](https://github.com/rails-api/active_model_serializers/pull/1103) Move `id` and `json_api_type` methods from `Serializer` to `JsonApi`. (@beauby)
|
||||
- [#1106](https://github.com/rails-api/active_model_serializers/pull/1106) Add Style enforcer (via Rubocop) (@bf4)
|
||||
- [#1079](https://github.com/rails-api/active_model_serializers/pull/1079) Add ArraySerializer#object like Serializer (@bf4)
|
||||
- [#1096](https://github.com/rails-api/active_model_serializers/pull/1096) Fix definition of serializer attributes with multiple calls to `attri… (@beauby)
|
||||
- [#1105](https://github.com/rails-api/active_model_serializers/pull/1105) Add ActiveRecord-backed fixtures. (@beauby)
|
||||
- [#1108](https://github.com/rails-api/active_model_serializers/pull/1108) Better lint (@bf4)
|
||||
- [#1102](https://github.com/rails-api/active_model_serializers/pull/1102) Remove remains of `embed` option. (@beauby)
|
||||
- [#1090](https://github.com/rails-api/active_model_serializers/pull/1090) Clarify AMS dependencies (@bf4)
|
||||
- [#1081](https://github.com/rails-api/active_model_serializers/pull/1081) Add configuration option to set resource type to singular/plural (@beauby)
|
||||
- [#1067](https://github.com/rails-api/active_model_serializers/pull/1067) Fix warnings (@bf4)
|
||||
- [#1066](https://github.com/rails-api/active_model_serializers/pull/1066) Adding appveyor to the project (@joaomdmoura, @Eric-Guo, @bf4)
|
||||
- [#1071](https://github.com/rails-api/active_model_serializers/pull/1071) Make testing suite running and pass in Windows (@Eric-Guo, @bf4)
|
||||
- [#1041](https://github.com/rails-api/active_model_serializers/pull/1041) Adding pagination links (@bacarini)
|
||||
* adds support for `pagination links` at top level of JsonApi adapter
|
||||
- [#1063](https://github.com/rails-api/active_model_serializers/pull/1063) Lead by example: lint PORO model (@bf4)
|
||||
- [#1](https://github.com/rails-api/active_model_serializers/pull/1) Test caller line parsing and digesting (@bf4)
|
||||
- [#1048](https://github.com/rails-api/active_model_serializers/pull/1048) Let FlattenJson adapter decide it doesn't include meta (@bf4)
|
||||
- [#1060](https://github.com/rails-api/active_model_serializers/pull/1060) Update fragment cache to support namespaced objects (@aaronlerch)
|
||||
- [#1052](https://github.com/rails-api/active_model_serializers/pull/1052) Use underscored json_root when serializing a collection (@whatthewhat)
|
||||
- [#1051](https://github.com/rails-api/active_model_serializers/pull/1051) Fix some invalid JSON in docs (@tjschuck)
|
||||
- [#1049](https://github.com/rails-api/active_model_serializers/pull/1049) Fix incorrect s/options = {}/options ||= {} (@bf4)
|
||||
- [#1037](https://github.com/rails-api/active_model_serializers/pull/1037) allow for type attribute (@lanej)
|
||||
- [#1034](https://github.com/rails-api/active_model_serializers/pull/1034) allow id attribute to be overriden (@lanej)
|
||||
- [#1035](https://github.com/rails-api/active_model_serializers/pull/1035) Fixed Comments highlight (@artLopez)
|
||||
- [#1031](https://github.com/rails-api/active_model_serializers/pull/1031) Disallow to define multiple associations at once (@bolshakov)
|
||||
- [#1032](https://github.com/rails-api/active_model_serializers/pull/1032) Wrap railtie requirement with rescue (@elliotlarson)
|
||||
- [#1026](https://github.com/rails-api/active_model_serializers/pull/1026) Bump Version Number to 0.10.0.rc2 (@jfelchner)
|
||||
- [#985](https://github.com/rails-api/active_model_serializers/pull/985) Associations implementation refactoring (@bolshakov)
|
||||
- [#954](https://github.com/rails-api/active_model_serializers/pull/954) Encapsulate serialization in ActiveModel::SerializableResource (@bf4)
|
||||
- [#972](https://github.com/rails-api/active_model_serializers/pull/972) Capture app warnings on test run (@bf4)
|
||||
- [#1019](https://github.com/rails-api/active_model_serializers/pull/1019) Improve README.md (@baojjeu)
|
||||
- [#998](https://github.com/rails-api/active_model_serializers/pull/998) Changing root to model class name (@joaomdmoura)
|
||||
- [#1006](https://github.com/rails-api/active_model_serializers/pull/1006) Fix adapter inflection bug for api -> API (@bf4)
|
||||
- [#1016](https://github.com/rails-api/active_model_serializers/pull/1016) require rails/railtie before subclassing Rails::Railtie (@bf4)
|
||||
- [#1013](https://github.com/rails-api/active_model_serializers/pull/1013) Root option with empty array support (@vyrak, @mareczek)
|
||||
- [#994](https://github.com/rails-api/active_model_serializers/pull/994) Starting Docs structure (@joaomdmoura)
|
||||
- [#1007](https://github.com/rails-api/active_model_serializers/pull/1007) Bug fix for ArraySerializer json_key (@jiajiawang)
|
||||
- [#1003](https://github.com/rails-api/active_model_serializers/pull/1003) Fix transient test failures (@Rodrigora)
|
||||
- [#996](https://github.com/rails-api/active_model_serializers/pull/996) Add linter for serializable resource (@bf4)
|
||||
- [#990](https://github.com/rails-api/active_model_serializers/pull/990) Adding json-api meta test (@joaomdmoura)
|
||||
- [#984](https://github.com/rails-api/active_model_serializers/pull/984) Add option "key" to serializer associations (@Rodrigora)
|
||||
- [#982](https://github.com/rails-api/active_model_serializers/pull/982) Fix typo (@bf4)
|
||||
- [#981](https://github.com/rails-api/active_model_serializers/pull/981) Remove unused PORO#to_param (@bf4)
|
||||
- [#978](https://github.com/rails-api/active_model_serializers/pull/978) fix generators template bug (@regonn)
|
||||
- [#975](https://github.com/rails-api/active_model_serializers/pull/975) Fixes virtual value not being used (@GriffinHeart)
|
||||
- [#970](https://github.com/rails-api/active_model_serializers/pull/970) Fix transient tests failures (@Rodrigora)
|
||||
- [#962](https://github.com/rails-api/active_model_serializers/pull/962) Rendering objects that doesn't have serializers (@bf4, @joaomdmoura, @JustinAiken)
|
||||
- [#939](https://github.com/rails-api/active_model_serializers/pull/939) Use a more precise generated cache key (@aaronlerch)
|
||||
- [#971](https://github.com/rails-api/active_model_serializers/pull/971) Restore has_one to generator (@bf4)
|
||||
- [#965](https://github.com/rails-api/active_model_serializers/pull/965) options fedault valueserializable_hash and as_json (@bf4)
|
||||
- [#959](https://github.com/rails-api/active_model_serializers/pull/959) TYPO on README.md (@kangkyu)
|
||||
|
||||
### [v0.10.0.rc2 (2015-06-16)](https://github.com/rails-api/active_model_serializers/compare/v0.10.0.rc1...v0.10.0.rc2)
|
||||
- [#958](https://github.com/rails-api/active_model_serializers/pull/958) Splitting json adapter into two (@joaomdmoura)
|
||||
* adds FlattenJSON as default adapter
|
||||
- [#953](https://github.com/rails-api/active_model_serializers/pull/953) use model name to determine the type (@lsylvester)
|
||||
* uses model name to determine the type
|
||||
- [#949](https://github.com/rails-api/active_model_serializers/pull/949) Don't pass serializer option to associated serializers (@bf4, @edwardloveall)
|
||||
- [#902](https://github.com/rails-api/active_model_serializers/pull/902) Added serializer file digest to the cache_key (@cristianbica)
|
||||
- [#948](https://github.com/rails-api/active_model_serializers/pull/948) AMS supports JSONAPI 1.0 instead of RC4 (@SeyZ)
|
||||
- [#936](https://github.com/rails-api/active_model_serializers/pull/936) Include meta when using json adapter with custom root (@chrisbranson)
|
||||
- [#942](https://github.com/rails-api/active_model_serializers/pull/942) Small code styling issue (@thiagofm)
|
||||
- [#930](https://github.com/rails-api/active_model_serializers/pull/930) Reverting PR #909 (@joaomdmoura)
|
||||
- [#924](https://github.com/rails-api/active_model_serializers/pull/924) Avoid unnecessary calls to attribute methods when fragment caching (@navinpeiris)
|
||||
- [#925](https://github.com/rails-api/active_model_serializers/pull/925) Updates JSON API Adapter to generate RC4 schema (@benedikt)
|
||||
* adds JSON API support 1.0
|
||||
- [#918](https://github.com/rails-api/active_model_serializers/pull/918) Adding rescue_with_handler to clear state (@ryansch)
|
||||
- [#909](https://github.com/rails-api/active_model_serializers/pull/909) Defining Json-API Adapter as Default (@joaomdmoura)
|
||||
* remove root key option and split JSON adapter
|
||||
- [#914](https://github.com/rails-api/active_model_serializers/pull/914) Prevent possible duplicated attributes in serializer (@groyoh)
|
||||
- [#880](https://github.com/rails-api/active_model_serializers/pull/880) Inabling subclasses serializers to inherit attributes (@groyoh)
|
||||
- [#913](https://github.com/rails-api/active_model_serializers/pull/913) Avoiding the serializer option when instantiating a new one for ArraySerializer Fixed #911 (@groyoh)
|
||||
- [#897](https://github.com/rails-api/active_model_serializers/pull/897) Allow to define custom serializer for given class (@imanel)
|
||||
- [#892](https://github.com/rails-api/active_model_serializers/pull/892) Fixed a bug that appeared when json adapter serialize a nil association (@groyoh)
|
||||
- [#895](https://github.com/rails-api/active_model_serializers/pull/895) Adding a test to cover 'meta' and 'meta_key' attr_readers (@adomokos)
|
||||
- [#894](https://github.com/rails-api/active_model_serializers/pull/894) Fixing typos in README.md (@adomokos)
|
||||
- [#888](https://github.com/rails-api/active_model_serializers/pull/888) Changed duplicated test name in action controller test (@groyoh)
|
||||
- [#890](https://github.com/rails-api/active_model_serializers/pull/890) Remove unused method `def_serializer` (@JustinAiken)
|
||||
- [#887](https://github.com/rails-api/active_model_serializers/pull/887) Fixing tests on JRuby (@joaomdmoura)
|
||||
- [#885](https://github.com/rails-api/active_model_serializers/pull/885) Updates rails versions for test and dev (@tonyta)
|
||||
|
||||
### [v0.10.0.rc1 (2015-04-22)](https://github.com/rails-api/active_model_serializers/compare/86fc7d7227f3ce538fcb28c1e8c7069ce311f0e1...v0.10.0.rc1)
|
||||
- [#810](https://github.com/rails-api/active_model_serializers/pull/810) Adding Fragment Cache to AMS (@joaomdmoura)
|
||||
* adds fragment cache support
|
||||
- [#868](https://github.com/rails-api/active_model_serializers/pull/868) Fixed a bug that appears when a nil association is included (@groyoh)
|
||||
- [#861](https://github.com/rails-api/active_model_serializers/pull/861) README: Add emphasis to single-word difference (@machty)
|
||||
- [#858](https://github.com/rails-api/active_model_serializers/pull/858) Included resource fixes (@mateomurphy)
|
||||
- [#853](https://github.com/rails-api/active_model_serializers/pull/853) RC3 Updates for JSON API (@mateomurphy)
|
||||
- [#852](https://github.com/rails-api/active_model_serializers/pull/852) Fix options merge order in `each_association` (@mateomurphy)
|
||||
- [#850](https://github.com/rails-api/active_model_serializers/pull/850) Use association value for determining serializer used (@mateomurphy)
|
||||
- [#843](https://github.com/rails-api/active_model_serializers/pull/843) Remove the mailing list from the README (@JoshSmith)
|
||||
- [#842](https://github.com/rails-api/active_model_serializers/pull/842) Add notes on how you can help to contributing documentation (@JoshSmith)
|
||||
- [#833](https://github.com/rails-api/active_model_serializers/pull/833) Cache serializers for class (@lsylvester)
|
||||
- [#837](https://github.com/rails-api/active_model_serializers/pull/837) Store options in array serializers (@kurko)
|
||||
- [#836](https://github.com/rails-api/active_model_serializers/pull/836) Makes passed in options accessible inside serializers (@kurko)
|
||||
- [#773](https://github.com/rails-api/active_model_serializers/pull/773) Make json api adapter 'include' option accept an array (@sweatypitts)
|
||||
- [#830](https://github.com/rails-api/active_model_serializers/pull/830) Add contributing readme (@JoshSmith)
|
||||
- [#811](https://github.com/rails-api/active_model_serializers/pull/811) Reimplement serialization scope and scope_name (@mateomurphy)
|
||||
- [#725](https://github.com/rails-api/active_model_serializers/pull/725) Support has_one to be compatible with 0.8.x (@ggordon)
|
||||
* adds `has_one` attribute for backwards compatibility
|
||||
- [#822](https://github.com/rails-api/active_model_serializers/pull/822) Replace has_one with attribute in template (@bf4)
|
||||
- [#821](https://github.com/rails-api/active_model_serializers/pull/821) Fix explicit serializer for associations (@wjordan)
|
||||
- [#798](https://github.com/rails-api/active_model_serializers/pull/798) Fix lost test `test_include_multiple_posts_and_linked` (@donbobka)
|
||||
- [#807](https://github.com/rails-api/active_model_serializers/pull/807) Add Overriding attribute methods section to README. (@alexstophel)
|
||||
- [#693](https://github.com/rails-api/active_model_serializers/pull/693) Cache Support at AMS 0.10.0 (@joaomdmoura)
|
||||
* adds cache support to attributes and associations.
|
||||
- [#792](https://github.com/rails-api/active_model_serializers/pull/792) Association overrides (@kurko)
|
||||
* adds method to override association
|
||||
- [#794](https://github.com/rails-api/active_model_serializers/pull/794) add to_param for correct URL generation (@carlesjove)
|
||||
|
||||
### v0.10.0-pre
|
||||
|
||||
- [Introduce Adapter](https://github.com/rails-api/active_model_serializers/commit/f00fe5595ddf741dc26127ed8fe81adad833ead5)
|
||||
- Prefer `ActiveModel::Serializer` to `ActiveModelSerializers`:
|
||||
- [Namespace](https://github.com/rails-api/active_model_serializers/commit/729a823868e8c7ac86c653fcc7100ee511e08cb6#diff-fe7aa2941c19a41ccea6e52940d84016).
|
||||
- [README](https://github.com/rails-api/active_model_serializers/commit/4a2d9853ba7486acc1747752982aa5650e7fd6e9).
|
||||
15
CHANGELOG-prehistory.md
Normal file
15
CHANGELOG-prehistory.md
Normal file
@ -0,0 +1,15 @@
|
||||
## Prehistory
|
||||
|
||||
- [Changing Serialization/Serializers namespace to `Serializable` (November 30, 2011)](https://github.com/rails/rails/commit/8896b4fdc8a543157cdf4dfc378607ebf6c10ab0)
|
||||
- [Merge branch 'serializers'. This implements the ActiveModel::Serializer object. Includes code, tests, generators and guides. From José and Yehuda with love.](https://github.com/rails/rails/commit/fcacc6986ab60f1fb2e423a73bf47c7abd7b191d)
|
||||
- But [was reverted](https://github.com/rails/rails/commit/5b2eb64ceb08cd005dc06b721935de5853971473).
|
||||
'[Revert the serializers API as other alternatives are now also under discussion](https://github.com/rails/rails/commit/0a4035b12a6c59253cb60f9e3456513c6a6a9d33)'.
|
||||
- [Proposed Implementation to Rails 3.2 by @wycats and @josevalim (November 25, 2011)](https://github.com/rails/rails/pull/3753)
|
||||
- [Creation of `ActionController::Serialization`, initial serializer
|
||||
support (September, 26 2011)](https://github.com/rails/rails/commit/8ff7693a8dc61f43fc4eaf72ed24d3b8699191fe).
|
||||
- [Docs and CHANGELOG](https://github.com/rails/rails/commit/696d01f7f4a8ed787924a41cce6df836cd73c46f)
|
||||
- [Deprecation of ActiveModel::Serialization to ActiveModel::Serializable](https://github.com/rails/rails/blob/696d01f7f4a8ed787924a41cce6df836cd73c46f/activemodel/lib/active_model/serialization.rb)
|
||||
- [Creation of `ActiveModel::Serialization` from `ActiveModel::Serializer` in Rails (2009)](https://github.com/rails/rails/commit/c6bc8e662614be711f45a8d4b231d5f993b024a7#diff-d029b9768d8df0407a35804a468e3ae5)
|
||||
- [Integration of `ActiveModel::Serializer` into `ActiveRecord::Serialization`](https://github.com/rails/rails/commit/783db25e0c640c1588732967a87d65c10fddc08e)
|
||||
- [Creation of `ActiveModel::Serializer` in Rails (2009)](https://github.com/rails/rails/commit/d2b78b3594b9cc9870e6a6ebfeb2e56d00e6ddb8#diff-80d5beeced9bdc24ca2b04a201543bdd)
|
||||
- [Creation of `ActiveModel::Serializers::JSON` in Rails (2009)](https://github.com/rails/rails/commit/fbdf706fffbfb17731a1f459203d242414ef5086)
|
||||
199
CHANGELOG.md
199
CHANGELOG.md
@ -1,200 +1,19 @@
|
||||
## 0.09.x
|
||||
## Dev
|
||||
|
||||
### [0-9-stable](https://github.com/rails-api/active_model_serializers/compare/v0.9.8...0-9-stable)
|
||||
### [master (unreleased)](https://github.com/rails-api/active_model_serializers/compare/master..dev)
|
||||
|
||||
### [v0.9.8 (2020-12-10)](https://github.com/rails-api/active_model_serializers/compare/v0.9.7...v0.9.8)
|
||||
|
||||
- [#2373](https://github.com/rails-api/active_model_serializers/pull/2373) Fix Rails 6.0 deprecation warnings. (@supremebeing7)
|
||||
|
||||
### [v0.9.7 (2017-05-01)](https://github.com/rails-api/active_model_serializers/compare/v0.9.6...v0.9.7)
|
||||
|
||||
- [#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)
|
||||
|
||||
### [v0.9.6 (2017-01-10)](https://github.com/rails-api/active_model_serializers/compare/v0.9.5...v0.9.6)
|
||||
|
||||
- [#2008](https://github.com/rails-api/active_model_serializers/pull/2008) Fix warning on Thor. (@kirs)
|
||||
|
||||
### [v0.9.5 (2016-03-30)](https://github.com/rails-api/active_model_serializers/compare/v0.9.4...v0.9.5)
|
||||
|
||||
- [#1607](https://github.com/rails-api/active_model_serializers/pull/1607) Merge multiple nested associations. (@Hirtenknogger)
|
||||
|
||||
### [v0.9.4 (2016-01-05)](https://github.com/rails-api/active_model_serializers/compare/v0.9.3...v0.9.4)
|
||||
|
||||
- [#752](https://github.com/rails-api/active_model_serializers/pull/752) Tiny improvement of README 0-9-stable (@basiam)
|
||||
- [#749](https://github.com/rails-api/active_model_serializers/pull/749) remove trailing whitespace (@shwoodard)
|
||||
- [#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)
|
||||
- [#790](https://github.com/rails-api/active_model_serializers/pull/790) pass context to ArraySerializer (@lanej)
|
||||
- [#797](https://github.com/rails-api/active_model_serializers/pull/797) Fix and test for #490 (@afn)
|
||||
- [#813](https://github.com/rails-api/active_model_serializers/pull/813) Allow to define custom serializer for given class (@jtomaszewski)
|
||||
- [#841](https://github.com/rails-api/active_model_serializers/pull/841) Fix issue with embedding multiple associations under the same root key (@antstorm)
|
||||
- [#748](https://github.com/rails-api/active_model_serializers/pull/748) Propagate serialization_options across associations (@raphaelpereira)
|
||||
|
||||
### [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)
|
||||
Breaking changes:
|
||||
|
||||
Features:
|
||||
- [#774](https://github.com/rails-api/active_model_serializers/pull/774) Fix nested include attributes (@nhocki)
|
||||
- [#771](https://github.com/rails-api/active_model_serializers/pull/771) Make linked resource type names consistent with root names (@sweatypitts)
|
||||
- [#696](https://github.com/rails-api/active_model_serializers/pull/696) Explicitly set serializer for associations (@ggordon)
|
||||
- [#700](https://github.com/rails-api/active_model_serializers/pull/700) sparse fieldsets (@arenoir)
|
||||
- [#768](https://github.com/rails-api/active_model_serializers/pull/768) Adds support for `meta` and `meta_key` attribute (@kurko)
|
||||
|
||||
### [v0.9.2](https://github.com/rails-api/active_model_serializers/compare/v0.9.1...v0.9.2)
|
||||
Fixes:
|
||||
|
||||
### [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)
|
||||
Misc:
|
||||
|
||||
- [#707](https://github.com/rails-api/active_model_serializers/pull/707) A Friendly Note on Which AMS Version to Use (@jherdman)
|
||||
- [#730](https://github.com/rails-api/active_model_serializers/pull/730) Fixes nested has_many links in JSONAPI (@kurko)
|
||||
- [#718](https://github.com/rails-api/active_model_serializers/pull/718) Allow overriding the adapter with render option (@ggordon)
|
||||
- [#720](https://github.com/rails-api/active_model_serializers/pull/720) Rename attribute with :key (0.8.x compatibility) (@ggordon)
|
||||
- [#728](https://github.com/rails-api/active_model_serializers/pull/728) Use type as key for linked resources (@kurko)
|
||||
- [#729](https://github.com/rails-api/active_model_serializers/pull/729) Use the new beta build env on Travis (@joshk)
|
||||
- [#703](https://github.com/rails-api/active_model_serializers/pull/703) Support serializer and each_serializer options in renderer (@ggordon, @mieko)
|
||||
- [#727](https://github.com/rails-api/active_model_serializers/pull/727) Includes links inside of linked resources (@kurko)
|
||||
- [#726](https://github.com/rails-api/active_model_serializers/pull/726) Bugfix: include nested has_many associations (@kurko)
|
||||
- [#722](https://github.com/rails-api/active_model_serializers/pull/722) Fix infinite recursion (@ggordon)
|
||||
- [#1](https://github.com/rails-api/active_model_serializers/pull/1) Allow for the implicit use of ArraySerializer when :each_serializer is specified (@mieko)
|
||||
- [#692](https://github.com/rails-api/active_model_serializers/pull/692) Include 'linked' member for json-api collections (@ggordon)
|
||||
- [#714](https://github.com/rails-api/active_model_serializers/pull/714) Define as_json instead of to_json (@guilleiguaran)
|
||||
- [#710](https://github.com/rails-api/active_model_serializers/pull/710) JSON-API: Don't include linked section if associations are empty (@guilleiguaran)
|
||||
- [#711](https://github.com/rails-api/active_model_serializers/pull/711) Fixes rbx gems bundling on TravisCI (@kurko)
|
||||
- [#709](https://github.com/rails-api/active_model_serializers/pull/709) Add type key when association name is different than object type (@guilleiguaran)
|
||||
- [#708](https://github.com/rails-api/active_model_serializers/pull/708) Handle correctly null associations (@guilleiguaran)
|
||||
- [#691](https://github.com/rails-api/active_model_serializers/pull/691) Fix embed option for associations (@jacob-s-son)
|
||||
- [#689](https://github.com/rails-api/active_model_serializers/pull/689) Fix support for custom root in JSON-API adapter (@guilleiguaran)
|
||||
- [#685](https://github.com/rails-api/active_model_serializers/pull/685) Serialize ids as strings in JSON-API adapter (@guilleiguaran)
|
||||
- [#684](https://github.com/rails-api/active_model_serializers/pull/684) Refactor adapters to implement support for array serialization (@guilleiguaran)
|
||||
- [#682](https://github.com/rails-api/active_model_serializers/pull/682) Include root by default in JSON-API serializers (@guilleiguaran)
|
||||
- [#625](https://github.com/rails-api/active_model_serializers/pull/625) Add DSL for urls (@JordanFaust)
|
||||
- [#677](https://github.com/rails-api/active_model_serializers/pull/677) Add support for embed: :ids option for in associations (@guilleiguaran)
|
||||
- [#681](https://github.com/rails-api/active_model_serializers/pull/681) Check superclasses for Serializers (@quainjn)
|
||||
- [#680](https://github.com/rails-api/active_model_serializers/pull/680) Add support for root keys (@NullVoxPopuli)
|
||||
- [#675](https://github.com/rails-api/active_model_serializers/pull/675) Support Rails 4.2.0 (@tricknotes)
|
||||
- [#667](https://github.com/rails-api/active_model_serializers/pull/667) Require only activemodel instead of full rails (@guilleiguaran)
|
||||
- [#653](https://github.com/rails-api/active_model_serializers/pull/653) Add "_test" suffix to JsonApi::HasManyTest filename. (@alexgenco)
|
||||
- [#631](https://github.com/rails-api/active_model_serializers/pull/631) Update build badge URL (@craiglittle)
|
||||
## [0.10.x](CHANGELOG-0-10.md)
|
||||
|
||||
### [v0.9.0](https://github.com/rails-api/active_model_serializers/compare/v0.9.0.alpha1...v0.9.0)
|
||||
## [0.09.x](CHANGELOG-0-09.md)
|
||||
|
||||
### [0.9.0.alpha1 - January 7, 2014](https://github.com/rails-api/active_model_serializers/compare/d72b66d4c...v0.9.0.alpha1)
|
||||
## [0.08.x](CHANGELOG-0-08.md)
|
||||
|
||||
### 0.9.0.pre
|
||||
|
||||
* The following methods were removed
|
||||
- Model#active\_model\_serializer
|
||||
- Serializer#include!
|
||||
- Serializer#include?
|
||||
- Serializer#attr\_disabled=
|
||||
- Serializer#cache
|
||||
- Serializer#perform\_caching
|
||||
- Serializer#schema (needs more discussion)
|
||||
- Serializer#attribute
|
||||
- Serializer#include\_#{name}? (filter method added)
|
||||
- Serializer#attributes (took a hash)
|
||||
|
||||
* The following things were added
|
||||
- Serializer#filter method
|
||||
- CONFIG object
|
||||
|
||||
* Remove support for ruby 1.8 versions.
|
||||
|
||||
* Require rails >= 3.2.
|
||||
|
||||
* Serializers for associations are being looked up in a parent serializer's namespace first. Same with controllers' namespaces.
|
||||
|
||||
* Added a "prefix" option in case you want to use a different version of serializer.
|
||||
|
||||
* Serializers default namespace can be set in `default_serializer_options` and inherited by associations.
|
||||
|
||||
# VERSION 0.9.0.pre
|
||||
|
||||
* The following methods were removed
|
||||
- Model#active\_model\_serializer
|
||||
- Serializer#include!
|
||||
- Serializer#include?
|
||||
- Serializer#attr\_disabled=
|
||||
- Serializer#cache
|
||||
- Serializer#perform\_caching
|
||||
- Serializer#schema (needs more discussion)
|
||||
- Serializer#attribute
|
||||
- Serializer#include\_#{name}? (filter method added)
|
||||
- Serializer#attributes (took a hash)
|
||||
|
||||
* The following things were added
|
||||
- Serializer#filter method
|
||||
- CONFIG object
|
||||
|
||||
* Remove support for ruby 1.8 versions.
|
||||
|
||||
* Require rails >= 3.2.
|
||||
|
||||
* Serializers for associations are being looked up in a parent serializer's namespace first. Same with controllers' namespaces.
|
||||
|
||||
* Added a "prefix" option in case you want to use a different version of serializer.
|
||||
|
||||
* Serializers default namespace can be set in `default_serializer_options` and inherited by associations.
|
||||
|
||||
# VERSION 0.8.1
|
||||
|
||||
* Fix bug whereby a serializer using 'options' would blow up.
|
||||
|
||||
# VERSION 0.8.0
|
||||
|
||||
* Attributes can now have optional types.
|
||||
|
||||
* A new DefaultSerializer ensures that POROs behave the same way as ActiveModels.
|
||||
|
||||
* If you wish to override ActiveRecord::Base#to\_Json, you can now require
|
||||
'active\_record/serializer\_override'. We don't recommend you do this, but
|
||||
many users do, so we've left it optional.
|
||||
|
||||
* Fixed a bug where ActionController wouldn't always have MimeResponds.
|
||||
|
||||
* An optional caching feature allows you to cache JSON & hashes that AMS uses.
|
||||
Adding 'cached true' to your Serializers will turn on this cache.
|
||||
|
||||
* URL helpers used inside of Engines now work properly.
|
||||
|
||||
* Serializers now can filter attributes with `only` and `except`:
|
||||
|
||||
```
|
||||
UserSerializer.new(user, only: [:first_name, :last_name])
|
||||
UserSerializer.new(user, except: :first_name)
|
||||
```
|
||||
|
||||
* Basic Mongoid support. We now include our mixins in the right place.
|
||||
|
||||
* On Ruby 1.8, we now generate an `id` method that properly serializes `id`
|
||||
columns. See issue #127 for more.
|
||||
|
||||
* Add an alias for `scope` method to be the name of the context. By default
|
||||
this is `current_user`. The name is automatically set when using
|
||||
`serialization_scope` in the controller.
|
||||
|
||||
* Pass through serialization options (such as `:include`) when a model
|
||||
has no serializer defined.
|
||||
|
||||
# VERSION 0.7.0
|
||||
|
||||
* ```embed_key``` option to allow embedding by attributes other than IDs
|
||||
* Fix rendering nil with custom serializer
|
||||
* Fix global ```self.root = false```
|
||||
* Add support for specifying the serializer for an association as a String
|
||||
* Able to specify keys on the attributes method
|
||||
* Serializer Reloading via ActiveSupport::DescendantsTracker
|
||||
* Reduce double map to once; Fixes datamapper eager loading.
|
||||
|
||||
# VERSION 0.6.0
|
||||
|
||||
* Serialize sets properly
|
||||
* Add root option to ArraySerializer
|
||||
* Support polymorphic associations
|
||||
* Support :each_serializer in ArraySerializer
|
||||
* Add `scope` method to easily access the scope in the serializer
|
||||
* Fix regression with Rails 3.2.6; add Rails 4 support
|
||||
* Allow serialization_scope to be disabled with serialization_scope nil
|
||||
* Array serializer should support pure ruby objects besides serializers
|
||||
|
||||
# VERSION 0.5.0
|
||||
|
||||
* First tagged version
|
||||
* Changes generators to always generate an ApplicationSerializer
|
||||
## [Prehistory](CHANGELOG-prehistory.md)
|
||||
|
||||
74
CODE_OF_CONDUCT.md
Normal file
74
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,74 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting one of the owners listed at https://rubygems.org/gems/active_model_serializers. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
104
CONTRIBUTING.md
104
CONTRIBUTING.md
@ -1,20 +1,100 @@
|
||||
Contributing to AMS
|
||||
===================
|
||||
## Have an issue?
|
||||
|
||||
First of all, **thank you**!
|
||||
Before opening an issue, try the following:
|
||||
|
||||
Now, for the details:
|
||||
##### Consult the documentation
|
||||
|
||||
Please file issues on the [GitHub Issues
|
||||
list](https://github.com/rails-api/active_model_serializers/issues).
|
||||
See if your issue can be resolved by information in the [documentation](README.md).
|
||||
|
||||
Please discuss new features or ask for feedback about a new feature [on
|
||||
rails-api-core](https://groups.google.com/forum/#!forum/rails-api-core).
|
||||
##### Check for an existing issue
|
||||
|
||||
If you want a feature implemented, the best way to get it done is to submit a
|
||||
pull request that implements it. Tests and docs would be nice.
|
||||
Take a look at the issues to see if a similar one has already been created. If
|
||||
one exists, please add any additional information that might expedite
|
||||
resolution.
|
||||
|
||||
Please include a CHANGELOG with all entries that change behavior.
|
||||
#### Open an issue
|
||||
|
||||
:heart: :sparkling_heart: :heart:
|
||||
If the documentation wasn't able to help resolve the issue and no issue already
|
||||
exists, please open a new issue with the following in mind:
|
||||
|
||||
- Please make sure only to include one issue per report. If you encounter
|
||||
multiple, unrelated issues, please report them as such.
|
||||
- Be detailed. Provide backtraces and example code when possible. Provide
|
||||
information about your environment. e.g., Ruby version, rails version, etc.
|
||||
- Own your issue. Actively participate in the discussion and help drive the
|
||||
issue to closure.
|
||||
- If you resolve your own issue, please share the details on the issue and close
|
||||
it out. Others might have the same issue and sharing solutions is helpful.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributing can be done in many ways and is not exclusive to code. If you have
|
||||
thoughts on a particular issue or feature, we encourage you to open new issues
|
||||
for discussion or add your comments to existing ones.
|
||||
|
||||
#### Pull requests
|
||||
|
||||
We also gladly welcome pull requests. When preparing to work on pull request,
|
||||
please adhere to these standards:
|
||||
|
||||
- Base work on the relevant branch:
|
||||
[0.10-stable](https://github.com/rails-api/active_model_serializers/tree/0-10-stable)
|
||||
or
|
||||
[0.9-stable](https://github.com/rails-api/active_model_serializers/tree/0-9-stable)
|
||||
or
|
||||
[0.8-stable](https://github.com/rails-api/active_model_serializers/tree/0-8-stable)
|
||||
- Squash your commits and regularly rebase off master.
|
||||
- Provide a description of the changes contained in the pull request.
|
||||
- Note any specific areas that should be reviewed.
|
||||
- Include tests.
|
||||
- The test suite must pass on [supported Ruby versions](.travis.yml)
|
||||
- Include updates to the [documentation](docs)
|
||||
where applicable.
|
||||
- Update the
|
||||
[CHANGELOG](CHANGELOG.md)
|
||||
to the appropriate sections with a brief description of the changes.
|
||||
- Do not change the VERSION file.
|
||||
|
||||
#### Running tests
|
||||
|
||||
Run all tests
|
||||
|
||||
`$ rake test`
|
||||
|
||||
Run a single test suite
|
||||
|
||||
`$ rake test TEST=path/to/test.rb`
|
||||
|
||||
Run a single test
|
||||
|
||||
`$ rake test TEST=path/to/test.rb TESTOPTS="--name=test_something"`
|
||||
|
||||
Run tests against different Rails versions by setting the RAILS_VERSION variable
|
||||
and bundling gems. (save this script somewhere executable and run from top of AMS repository)
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
rcommand='puts YAML.load_file("./.travis.yml")["env"]["matrix"].join(" ").gsub("RAILS_VERSION=", "")'
|
||||
versions=$(ruby -ryaml -e "$rcommand")
|
||||
|
||||
for version in ${versions[@]}; do
|
||||
export RAILS_VERSION="$version"
|
||||
rm -f Gemfile.lock
|
||||
bundle check || bundle --local || bundle
|
||||
bundle exec rake test
|
||||
if [ "$?" -eq 0 ]; then
|
||||
# green in ANSI
|
||||
echo -e "\033[32m **** Tests passed against Rails ${RAILS_VERSION} **** \033[0m"
|
||||
else
|
||||
# red in ANSI
|
||||
echo -e "\033[31m **** Tests failed against Rails ${RAILS_VERSION} **** \033[0m"
|
||||
read -p '[Enter] any key to continue, [q] to quit...' prompt
|
||||
if [ "$prompt" = 'q' ]; then
|
||||
unset RAILS_VERSION
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
unset RAILS_VERSION
|
||||
done
|
||||
```
|
||||
|
||||
586
DESIGN.textile
586
DESIGN.textile
@ -1,586 +0,0 @@
|
||||
<strong>This was the original design document for serializers.</strong> It is useful mostly for historical purposes as the public API has changed.
|
||||
|
||||
h2. Rails Serializers
|
||||
|
||||
This guide describes how to use Active Model serializers to build non-trivial JSON services in Rails. By reading this guide, you will learn:
|
||||
|
||||
* When to use the built-in Active Model serialization
|
||||
* When to use a custom serializer for your models
|
||||
* How to use serializers to encapsulate authorization concerns
|
||||
* How to create serializer templates to describe the application-wide structure of your serialized JSON
|
||||
* How to build resources not backed by a single database table for use with JSON services
|
||||
|
||||
This guide covers an intermediate topic and assumes familiarity with Rails conventions. It is suitable for applications that expose a
|
||||
JSON API that may return different results based on the authorization status of the user.
|
||||
|
||||
h3. Serialization
|
||||
|
||||
By default, Active Record objects can serialize themselves into JSON by using the `to_json` method. This method takes a series of additional
|
||||
parameter to control which properties and associations Rails should include in the serialized output.
|
||||
|
||||
When building a web application that uses JavaScript to retrieve JSON data from the server, this mechanism has historically been the primary
|
||||
way that Rails developers prepared their responses. This works great for simple cases, as the logic for serializing an Active Record object
|
||||
is neatly encapsulated in Active Record itself.
|
||||
|
||||
However, this solution quickly falls apart in the face of serialization requirements based on authorization. For instance, a web service
|
||||
may choose to expose additional information about a resource only if the user is entitled to access it. In addition, a JavaScript front-end
|
||||
may want information that is not neatly described in terms of serializing a single Active Record object, or in a different format than.
|
||||
|
||||
In addition, neither the controller nor the model seems like the correct place for logic that describes how to serialize an model object
|
||||
*for the current user*.
|
||||
|
||||
Serializers solve these problems by encapsulating serialization in an object designed for this purpose. If the default +to_json+ semantics,
|
||||
with at most a few configuration options serve your needs, by all means continue to use the built-in +to_json+. If you find yourself doing
|
||||
hash-driven-development in your controllers, juggling authorization logic and other concerns, serializers are for you!
|
||||
|
||||
h3. The Most Basic Serializer
|
||||
|
||||
A basic serializer is a simple Ruby object named after the model class it is serializing.
|
||||
|
||||
<pre lang="ruby">
|
||||
class PostSerializer
|
||||
def initialize(post, scope)
|
||||
@post, @scope = post, scope
|
||||
end
|
||||
|
||||
def as_json
|
||||
{ post: { title: @post.name, body: @post.body } }
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
A serializer is initialized with two parameters: the model object it should serialize and an authorization scope. By default, the
|
||||
authorization scope is the current user (+current_user+) but you can use a different object if you want. The serializer also
|
||||
implements an +as_json+ method, which returns a Hash that will be sent to the JSON encoder.
|
||||
|
||||
Rails will transparently use your serializer when you use +render :json+ in your controller.
|
||||
|
||||
<pre lang="ruby">
|
||||
class PostsController < ApplicationController
|
||||
def show
|
||||
@post = Post.find(params[:id])
|
||||
render json: @post
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
Because +respond_with+ uses +render :json+ under the hood for JSON requests, Rails will automatically use your serializer when
|
||||
you use +respond_with+ as well.
|
||||
|
||||
h4. +serializable_hash+
|
||||
|
||||
In general, you will want to implement +serializable_hash+ and +as_json+ to allow serializers to embed associated content
|
||||
directly. The easiest way to implement these two methods is to have +as_json+ call +serializable_hash+ and insert the root.
|
||||
|
||||
<pre lang="ruby">
|
||||
class PostSerializer
|
||||
def initialize(post, scope)
|
||||
@post, @scope = post, scope
|
||||
end
|
||||
|
||||
def serializable_hash
|
||||
{ title: @post.name, body: @post.body }
|
||||
end
|
||||
|
||||
def as_json
|
||||
{ post: serializable_hash }
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
h4. Authorization
|
||||
|
||||
Let's update our serializer to include the email address of the author of the post, but only if the current user has superuser
|
||||
access.
|
||||
|
||||
<pre lang="ruby">
|
||||
class PostSerializer
|
||||
def initialize(post, scope)
|
||||
@post, @scope = post, scope
|
||||
end
|
||||
|
||||
def as_json
|
||||
{ post: serializable_hash }
|
||||
end
|
||||
|
||||
def serializable_hash
|
||||
hash = post
|
||||
hash.merge!(super_data) if super?
|
||||
hash
|
||||
end
|
||||
|
||||
private
|
||||
def post
|
||||
{ title: @post.name, body: @post.body }
|
||||
end
|
||||
|
||||
def super_data
|
||||
{ email: @post.email }
|
||||
end
|
||||
|
||||
def super?
|
||||
@scope.superuser?
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
h4. Testing
|
||||
|
||||
One benefit of encapsulating our objects this way is that it becomes extremely straight-forward to test the serialization
|
||||
logic in isolation.
|
||||
|
||||
<pre lang="ruby">
|
||||
require "ostruct"
|
||||
|
||||
class PostSerializerTest < ActiveSupport::TestCase
|
||||
# For now, we use a very simple authorization structure. These tests will need
|
||||
# refactoring if we change that.
|
||||
plebe = OpenStruct.new(super?: false)
|
||||
god = OpenStruct.new(super?: true)
|
||||
|
||||
post = OpenStruct.new(title: "Welcome to my blog!", body: "Blah blah blah", email: "tenderlove@gmail.com")
|
||||
|
||||
test "a regular user sees just the title and body" do
|
||||
json = PostSerializer.new(post, plebe).to_json
|
||||
hash = JSON.parse(json)
|
||||
|
||||
assert_equal post.title, hash.delete("title")
|
||||
assert_equal post.body, hash.delete("body")
|
||||
assert_empty hash
|
||||
end
|
||||
|
||||
test "a superuser sees the title, body and email" do
|
||||
json = PostSerializer.new(post, god).to_json
|
||||
hash = JSON.parse(json)
|
||||
|
||||
assert_equal post.title, hash.delete("title")
|
||||
assert_equal post.body, hash.delete("body")
|
||||
assert_equal post.email, hash.delete("email")
|
||||
assert_empty hash
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
It's important to note that serializer objects define a clear interface specifically for serializing an existing object.
|
||||
In this case, the serializer expects to receive a post object with +name+, +body+ and +email+ attributes and an authorization
|
||||
scope with a +super?+ method.
|
||||
|
||||
By defining a clear interface, it's must easier to ensure that your authorization logic is behaving correctly. In this case,
|
||||
the serializer doesn't need to concern itself with how the authorization scope decides whether to set the +super?+ flag, just
|
||||
whether it is set. In general, you should document these requirements in your serializer files and programatically via tests.
|
||||
The documentation library +YARD+ provides excellent tools for describing this kind of requirement:
|
||||
|
||||
<pre lang="ruby">
|
||||
class PostSerializer
|
||||
# @param [~body, ~title, ~email] post the post to serialize
|
||||
# @param [~super] scope the authorization scope for this serializer
|
||||
def initialize(post, scope)
|
||||
@post, @scope = post, scope
|
||||
end
|
||||
|
||||
# ...
|
||||
end
|
||||
</pre>
|
||||
|
||||
h3. Attribute Sugar
|
||||
|
||||
To simplify this process for a number of common cases, Rails provides a default superclass named +ActiveModel::Serializer+
|
||||
that you can use to implement your serializers.
|
||||
|
||||
For example, you will sometimes want to simply include a number of existing attributes from the source model into the outputted
|
||||
JSON. In the above example, the +title+ and +body+ attributes were always included in the JSON. Let's see how to use
|
||||
+ActiveModel::Serializer+ to simplify our post serializer.
|
||||
|
||||
<pre lang="ruby">
|
||||
class PostSerializer < ActiveModel::Serializer
|
||||
attributes :title, :body
|
||||
|
||||
def serializable_hash
|
||||
hash = attributes
|
||||
hash.merge!(super_data) if super?
|
||||
hash
|
||||
end
|
||||
|
||||
private
|
||||
def super_data
|
||||
{ email: @post.email }
|
||||
end
|
||||
|
||||
def super?
|
||||
@scope.superuser?
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
First, we specified the list of included attributes at the top of the class. This will create an instance method called
|
||||
+attributes+ that extracts those attributes from the post model.
|
||||
|
||||
NOTE: Internally, +ActiveModel::Serializer+ uses +read_attribute_for_serialization+, which defaults to +read_attribute+, which defaults to +send+. So if you're rolling your own models for use with the serializer, you can use simple Ruby accessors for your attributes if you like.
|
||||
|
||||
Next, we use the attributes method in our +serializable_hash+ method, which allowed us to eliminate the +post+ method we hand-rolled
|
||||
earlier. We could also eliminate the +as_json+ method, as +ActiveModel::Serializer+ provides a default +as_json+ method for
|
||||
us that calls our +serializable_hash+ method and inserts a root. But we can go a step further!
|
||||
|
||||
<pre lang="ruby">
|
||||
class PostSerializer < ActiveModel::Serializer
|
||||
attributes :title, :body
|
||||
|
||||
private
|
||||
def attributes
|
||||
hash = super
|
||||
hash.merge!(email: post.email) if super?
|
||||
hash
|
||||
end
|
||||
|
||||
def super?
|
||||
@scope.superuser?
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
The superclass provides a default +initialize+ method as well as a default +serializable_hash+ method, which uses
|
||||
+attributes+. We can call +super+ to get the hash based on the attributes we declared, and then add in any additional
|
||||
attributes we want to use.
|
||||
|
||||
NOTE: +ActiveModel::Serializer+ will create an accessor matching the name of the current class for the resource you pass in. In this case, because we have defined a PostSerializer, we can access the resource with the +post+ accessor.
|
||||
|
||||
h3. Associations
|
||||
|
||||
In most JSON APIs, you will want to include associated objects with your serialized object. In this case, let's include
|
||||
the comments with the current post.
|
||||
|
||||
<pre lang="ruby">
|
||||
class PostSerializer < ActiveModel::Serializer
|
||||
attributes :title, :body
|
||||
has_many :comments
|
||||
|
||||
private
|
||||
def attributes
|
||||
hash = super
|
||||
hash.merge!(email: post.email) if super?
|
||||
hash
|
||||
end
|
||||
|
||||
def super?
|
||||
@scope.superuser?
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
The default +serializable_hash+ method will include the comments as embedded objects inside the post.
|
||||
|
||||
<pre lang="json">
|
||||
{
|
||||
post: {
|
||||
title: "Hello Blog!",
|
||||
body: "This is my first post. Isn't it fabulous!",
|
||||
comments: [
|
||||
{
|
||||
title: "Awesome",
|
||||
body: "Your first post is great"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
Rails uses the same logic to generate embedded serializations as it does when you use +render :json+. In this case,
|
||||
because you didn't define a +CommentSerializer+, Rails used the default +as_json+ on your comment object.
|
||||
|
||||
If you define a serializer, Rails will automatically instantiate it with the existing authorization scope.
|
||||
|
||||
<pre lang="ruby">
|
||||
class CommentSerializer
|
||||
def initialize(comment, scope)
|
||||
@comment, @scope = comment, scope
|
||||
end
|
||||
|
||||
def serializable_hash
|
||||
{ title: @comment.title }
|
||||
end
|
||||
|
||||
def as_json
|
||||
{ comment: serializable_hash }
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
If we define the above comment serializer, the outputted JSON will change to:
|
||||
|
||||
<pre lang="json">
|
||||
{
|
||||
post: {
|
||||
title: "Hello Blog!",
|
||||
body: "This is my first post. Isn't it fabulous!",
|
||||
comments: [{ title: "Awesome" }]
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
Let's imagine that our comment system allows an administrator to kill a comment, and we only want to allow
|
||||
users to see the comments they're entitled to see. By default, +has_many :comments+ will simply use the
|
||||
+comments+ accessor on the post object. We can override the +comments+ accessor to limit the comments used
|
||||
to just the comments we want to allow for the current user.
|
||||
|
||||
<pre lang="ruby">
|
||||
class PostSerializer < ActiveModel::Serializer
|
||||
attributes :title. :body
|
||||
has_many :comments
|
||||
|
||||
private
|
||||
def attributes
|
||||
hash = super
|
||||
hash.merge!(email: post.email) if super?
|
||||
hash
|
||||
end
|
||||
|
||||
def comments
|
||||
post.comments_for(scope)
|
||||
end
|
||||
|
||||
def super?
|
||||
@scope.superuser?
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
+ActiveModel::Serializer+ will still embed the comments, but this time it will use just the comments
|
||||
for the current user.
|
||||
|
||||
NOTE: The logic for deciding which comments a user should see still belongs in the model layer. In general, you should encapsulate concerns that require making direct Active Record queries in scopes or public methods on your models.
|
||||
|
||||
h4. Modifying Associations
|
||||
|
||||
You can also rename associations if required. Say for example you have an association that
|
||||
makes sense to be named one thing in your code, but another when data is serialized.
|
||||
You can use the <code:key</code> option to specify a different name for an association.
|
||||
Here is an example:
|
||||
|
||||
<pre lang="ruby">
|
||||
class UserSerializer < ActiveModel::Serializer
|
||||
has_many :followed_posts, key: :posts
|
||||
has_one :owned_account, key: :account
|
||||
end
|
||||
</pre>
|
||||
|
||||
Using the <code>:key</code> without a <code>:serializer</code> option will use implicit detection
|
||||
to determine a serializer. In this example, you'd have to define two classes: <code>PostSerializer</code>
|
||||
and <code>AccountSerializer</code>. You can also add the <code>:serializer</code> option
|
||||
to set it explicitly:
|
||||
|
||||
<pre lang="ruby">
|
||||
class UserSerializer < ActiveModel::Serializer
|
||||
has_many :followed_posts, key: :posts, serializer: CustomPostSerializer
|
||||
has_one :owne_account, key: :account, serializer: PrivateAccountSerializer
|
||||
end
|
||||
</pre>
|
||||
|
||||
h3. Customizing Associations
|
||||
|
||||
Not all front-ends expect embedded documents in the same form. In these cases, you can override the
|
||||
default +serializable_hash+, and use conveniences provided by +ActiveModel::Serializer+ to avoid having to
|
||||
build up the hash manually.
|
||||
|
||||
For example, let's say our front-end expects the posts and comments in the following format:
|
||||
|
||||
<pre lang="json">
|
||||
{
|
||||
post: {
|
||||
id: 1
|
||||
title: "Hello Blog!",
|
||||
body: "This is my first post. Isn't it fabulous!",
|
||||
comments: [1,2]
|
||||
},
|
||||
comments: [
|
||||
{
|
||||
id: 1
|
||||
title: "Awesome",
|
||||
body: "Your first post is great"
|
||||
},
|
||||
{
|
||||
id: 2
|
||||
title: "Not so awesome",
|
||||
body: "Why is it so short!"
|
||||
}
|
||||
]
|
||||
}
|
||||
</pre>
|
||||
|
||||
We could achieve this with a custom +as_json+ method. We will also need to define a serializer for comments.
|
||||
|
||||
<pre lang="ruby">
|
||||
class CommentSerializer < ActiveModel::Serializer
|
||||
attributes :id, :title, :body
|
||||
|
||||
# define any logic for dealing with authorization-based attributes here
|
||||
end
|
||||
|
||||
class PostSerializer < ActiveModel::Serializer
|
||||
attributes :title, :body
|
||||
has_many :comments
|
||||
|
||||
def as_json
|
||||
{ post: serializable_hash }.merge!(associations)
|
||||
end
|
||||
|
||||
def serializable_hash
|
||||
post_hash = attributes
|
||||
post_hash.merge!(association_ids)
|
||||
post_hash
|
||||
end
|
||||
|
||||
private
|
||||
def attributes
|
||||
hash = super
|
||||
hash.merge!(email: post.email) if super?
|
||||
hash
|
||||
end
|
||||
|
||||
def comments
|
||||
post.comments_for(scope)
|
||||
end
|
||||
|
||||
def super?
|
||||
@scope.superuser?
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
Here, we used two convenience methods: +associations+ and +association_ids+. The first,
|
||||
+associations+, creates a hash of all of the define associations, using their defined
|
||||
serializers. The second, +association_ids+, generates a hash whose key is the association
|
||||
name and whose value is an Array of the association's keys.
|
||||
|
||||
The +association_ids+ helper will use the overridden version of the association, so in
|
||||
this case, +association_ids+ will only include the ids of the comments provided by the
|
||||
+comments+ method.
|
||||
|
||||
|
||||
h3. Special Association Serializers
|
||||
|
||||
So far, associations defined in serializers use either the +as_json+ method on the model
|
||||
or the defined serializer for the association type. Sometimes, you may want to serialize
|
||||
associated models differently when they are requested as part of another resource than
|
||||
when they are requested on their own.
|
||||
|
||||
For instance, we might want to provide the full comment when it is requested directly,
|
||||
but only its title when requested as part of the post. To achieve this, you can define
|
||||
a serializer for associated objects nested inside the main serializer.
|
||||
|
||||
<pre lang="ruby">
|
||||
class PostSerializer < ActiveModel::Serializer
|
||||
class CommentSerializer < ActiveModel::Serializer
|
||||
attributes :id, :title
|
||||
end
|
||||
|
||||
# same as before
|
||||
# ...
|
||||
end
|
||||
</pre>
|
||||
|
||||
In other words, if a +PostSerializer+ is trying to serialize comments, it will first
|
||||
look for +PostSerializer::CommentSerializer+ before falling back to +CommentSerializer+
|
||||
and finally +comment.as_json+.
|
||||
|
||||
h3. Overriding the Defaults
|
||||
|
||||
h4. Authorization Scope
|
||||
|
||||
By default, the authorization scope for serializers is +:current_user+. This means
|
||||
that when you call +render json: @post+, the controller will automatically call
|
||||
its +current_user+ method and pass that along to the serializer's initializer.
|
||||
|
||||
If you want to change that behavior, simply use the +serialization_scope+ class
|
||||
method.
|
||||
|
||||
<pre lang="ruby">
|
||||
class PostsController < ApplicationController
|
||||
serialization_scope :current_app
|
||||
end
|
||||
</pre>
|
||||
|
||||
You can also implement an instance method called (no surprise) +serialization_scope+,
|
||||
which allows you to define a dynamic authorization scope based on the current request.
|
||||
|
||||
WARNING: If you use different objects as authorization scopes, make sure that they all implement whatever interface you use in your serializers to control what the outputted JSON looks like.
|
||||
|
||||
h3. Using Serializers Outside of a Request
|
||||
|
||||
The serialization API encapsulates the concern of generating a JSON representation of
|
||||
a particular model for a particular user. As a result, you should be able to easily use
|
||||
serializers, whether you define them yourself or whether you use +ActiveModel::Serializer+
|
||||
outside a request.
|
||||
|
||||
For instance, if you want to generate the JSON representation of a post for a user outside
|
||||
of a request:
|
||||
|
||||
<pre lang="ruby">
|
||||
user = get_user # some logic to get the user in question
|
||||
PostSerializer.new(post, user).to_json # reliably generate JSON output
|
||||
</pre>
|
||||
|
||||
If you want to generate JSON for an anonymous user, you should be able to use whatever
|
||||
technique you use in your application to generate anonymous users outside of a request.
|
||||
Typically, that means creating a new user and not saving it to the database:
|
||||
|
||||
<pre lang="ruby">
|
||||
user = User.new # create a new anonymous user
|
||||
PostSerializer.new(post, user).to_json
|
||||
</pre>
|
||||
|
||||
In general, the better you encapsulate your authorization logic, the more easily you
|
||||
will be able to use the serializer outside of the context of a request. For instance,
|
||||
if you use an authorization library like Cancan, which uses a uniform +user.can?(action, model)+,
|
||||
the authorization interface can very easily be replaced by a plain Ruby object for
|
||||
testing or usage outside the context of a request.
|
||||
|
||||
h3. Collections
|
||||
|
||||
So far, we've talked about serializing individual model objects. By default, Rails
|
||||
will serialize collections, including when using the +associations+ helper, by
|
||||
looping over each element of the collection, calling +serializable_hash+ on the element,
|
||||
and then grouping them by their type (using the plural version of their class name
|
||||
as the root).
|
||||
|
||||
For example, an Array of post objects would serialize as:
|
||||
|
||||
<pre lang="json">
|
||||
{
|
||||
posts: [
|
||||
{
|
||||
title: "FIRST POST!",
|
||||
body: "It's my first pooooost"
|
||||
},
|
||||
{ title: "Second post!",
|
||||
body: "Zomg I made it to my second post"
|
||||
}
|
||||
]
|
||||
}
|
||||
</pre>
|
||||
|
||||
If you want to change the behavior of serialized Arrays, you need to create
|
||||
a custom Array serializer.
|
||||
|
||||
<pre lang="ruby">
|
||||
class ArraySerializer < ActiveModel::ArraySerializer
|
||||
def serializable_array
|
||||
serializers.map do |serializer|
|
||||
serializer.serializable_hash
|
||||
end
|
||||
end
|
||||
|
||||
def as_json
|
||||
hash = { root => serializable_array }
|
||||
hash.merge!(associations)
|
||||
hash
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
When generating embedded associations using the +associations+ helper inside a
|
||||
regular serializer, it will create a new <code>ArraySerializer</code> with the
|
||||
associated content and call its +serializable_array+ method. In this case, those
|
||||
embedded associations will not recursively include associations.
|
||||
|
||||
When generating an Array using +render json: posts+, the controller will invoke
|
||||
the +as_json+ method, which will include its associations and its root.
|
||||
100
Gemfile
100
Gemfile
@ -1,100 +0,0 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gemspec
|
||||
|
||||
version = ENV["RAILS_VERSION"] || "4.2"
|
||||
|
||||
if version == 'master'
|
||||
gem 'rack', github: 'rack/rack'
|
||||
gem 'arel', github: 'rails/arel'
|
||||
gem 'rails', github: 'rails/rails'
|
||||
git 'https://github.com/rails/rails.git' do
|
||||
gem 'railties'
|
||||
gem 'activesupport'
|
||||
gem 'activemodel'
|
||||
gem 'actionpack'
|
||||
gem 'activerecord', group: :test
|
||||
# Rails 5
|
||||
gem 'actionview'
|
||||
end
|
||||
# Rails 5
|
||||
gem 'rails-controller-testing', github: 'rails/rails-controller-testing'
|
||||
else
|
||||
gem_version = "~> #{version}.0"
|
||||
gem 'rails', gem_version
|
||||
gem 'railties', gem_version
|
||||
gem 'activesupport', gem_version
|
||||
gem 'activemodel', gem_version
|
||||
gem 'actionpack', gem_version
|
||||
gem 'activerecord', gem_version, group: :test
|
||||
end
|
||||
|
||||
if RUBY_VERSION < '2'
|
||||
gem 'mime-types', [ '>= 2.6.2', '< 3' ]
|
||||
end
|
||||
|
||||
if ENV['CI']
|
||||
if RUBY_VERSION < '2.4'
|
||||
# Windows: An error occurred while installing nokogiri (1.8.0)
|
||||
gem 'nokogiri', '< 1.7', platforms: @windows_platforms
|
||||
# >= 4.0 requires ruby >= 2.5
|
||||
gem 'sprockets', '< 4.0'
|
||||
end
|
||||
|
||||
if RUBY_VERSION < '2.2'
|
||||
# >= 12.3 and < 13 requires ruby >= 2.0, rake >= 13 requires ruby >= 2.2
|
||||
gem 'rake', '< 12.3'
|
||||
# > 5.12 requires ruby >= 2.2
|
||||
gem 'minitest', '< 5.12'
|
||||
# >= 1.0 requires ruby >= 2.0
|
||||
gem 'thor', '< 1.0'
|
||||
end
|
||||
end
|
||||
|
||||
# https://github.com/bundler/bundler/blob/89a8778c19269561926cea172acdcda241d26d23/lib/bundler/dependency.rb#L30-L54
|
||||
@windows_platforms = [:mswin, :mingw, :x64_mingw]
|
||||
|
||||
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
tzinfo_platforms = @windows_platforms
|
||||
tzinfo_platforms += [:jruby] if version >= '4.1'
|
||||
gem 'tzinfo-data', platforms: tzinfo_platforms
|
||||
|
||||
group :bench do
|
||||
gem 'benchmark-ips', '>= 2.7.2'
|
||||
end
|
||||
|
||||
group :test do
|
||||
platforms(*(@windows_platforms + [:ruby])) do
|
||||
if version == 'master' || version >= '6'
|
||||
gem 'sqlite3', '~> 1.4'
|
||||
else
|
||||
gem 'sqlite3', '~> 1.3.13'
|
||||
end
|
||||
end
|
||||
platforms :jruby do
|
||||
if version == 'master' || version >= '6.0'
|
||||
gem 'activerecord-jdbcsqlite3-adapter', github: 'jruby/activerecord-jdbc-adapter'
|
||||
elsif version == '5.2'
|
||||
gem 'activerecord-jdbcsqlite3-adapter', '~> 52.0'
|
||||
elsif version == '5.1'
|
||||
gem 'activerecord-jdbcsqlite3-adapter', '~> 51.0'
|
||||
elsif version == '5.0'
|
||||
gem 'activerecord-jdbcsqlite3-adapter', '~> 50.0'
|
||||
else
|
||||
gem 'activerecord-jdbcsqlite3-adapter', '~> 1.3.0'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
unless ENV['CI']
|
||||
gem 'rubocop', '~> 0.34.0', require: false
|
||||
end
|
||||
|
||||
# 0.12 requires ruby 2.4
|
||||
if RUBY_VERSION < '2.4'
|
||||
gem 'simplecov', '< 0.12', require: false
|
||||
else
|
||||
gem 'simplecov', '~> 0.10', require: false
|
||||
end
|
||||
end
|
||||
@ -1,4 +1,6 @@
|
||||
Copyright (c) 2011-2012 José Valim & Yehuda Katz
|
||||
Copyright (c) 2014 Steve Klabnik
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
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
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
27
Rakefile
27
Rakefile
@ -1,24 +1,5 @@
|
||||
#!/usr/bin/env rake
|
||||
require "bundler/gem_tasks"
|
||||
require "rake/testtask"
|
||||
|
||||
desc 'Run tests'
|
||||
test_task = Rake::TestTask.new(:test) do |t|
|
||||
t.libs << 'test'
|
||||
t.pattern = 'test/**/*_test.rb'
|
||||
t.verbose = true
|
||||
end
|
||||
|
||||
task default: :test
|
||||
|
||||
desc 'Run tests in isolated processes'
|
||||
namespace :test do
|
||||
task :isolated do
|
||||
Dir[test_task.pattern].each do |file|
|
||||
cmd = ['ruby']
|
||||
test_task.libs.each { |l| cmd << '-I' << l }
|
||||
cmd << file
|
||||
sh cmd.join(' ')
|
||||
end
|
||||
end
|
||||
begin
|
||||
require 'bundler/setup'
|
||||
rescue LoadError
|
||||
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
||||
end
|
||||
|
||||
@ -1,26 +1,20 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# coding: utf-8
|
||||
|
||||
$:.unshift File.expand_path("../lib", __FILE__)
|
||||
require "active_model/serializer/version"
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = 'active_model_serializers'
|
||||
spec.version = "1.0.0-dev"
|
||||
spec.platform = Gem::Platform::RUBY
|
||||
spec.authors = ['Steve Klabnik']
|
||||
spec.email = ['steve@steveklabnik.com']
|
||||
spec.summary = 'Conventions-based JSON generation for Rails.'
|
||||
spec.description = 'ActiveModel::Serializers allows you to generate your JSON in an object-oriented and convention-driven manner.'
|
||||
spec.homepage = 'https://github.com/rails-api/active_model_serializers'
|
||||
spec.license = 'MIT'
|
||||
|
||||
Gem::Specification.new do |gem|
|
||||
gem.authors = ["José Valim", "Yehuda Katz", "Santiago Pastorino"]
|
||||
gem.email = ["jose.valim@gmail.com", "wycats@gmail.com", "santiago@wyeworks.com"]
|
||||
gem.description = %q{Making it easy to serialize models for client-side use}
|
||||
gem.summary = %q{Bringing consistency and object orientation to model serialization. Works great for client-side MVC frameworks!}
|
||||
gem.homepage = "https://github.com/rails-api/active_model_serializers"
|
||||
gem.license = 'MIT'
|
||||
spec.files = `git ls-files -z`.split("\x0")
|
||||
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
||||
spec.require_paths = ['lib']
|
||||
spec.executables = []
|
||||
|
||||
gem.files = Dir['README.md', 'CHANGELOG.md', 'CONTRIBUTING.md', 'DESIGN.textile', 'MIT-LICENSE', 'lib/**/*', 'test/**/*']
|
||||
gem.test_files = Dir['test/**/*']
|
||||
|
||||
gem.name = "active_model_serializers"
|
||||
gem.require_paths = ["lib"]
|
||||
gem.version = ActiveModel::Serializer::VERSION
|
||||
|
||||
gem.required_ruby_version = ">= 1.9.3"
|
||||
|
||||
gem.add_dependency "activemodel", ">= 3.2"
|
||||
gem.add_dependency "concurrent-ruby", "~> 1.0"
|
||||
gem.add_development_dependency "rails", ">= 3.2"
|
||||
spec.required_ruby_version = '>= 2.1'
|
||||
end
|
||||
|
||||
38
appveyor.yml
38
appveyor.yml
@ -1,27 +1,11 @@
|
||||
version: '{build}'
|
||||
|
||||
skip_tags: true
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- ruby_version: "200"
|
||||
- ruby_version: "200-x64"
|
||||
- ruby_version: "21"
|
||||
- ruby_version: "21-x64"
|
||||
|
||||
cache:
|
||||
- vendor/bundle
|
||||
|
||||
install:
|
||||
- SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
|
||||
- ruby --version
|
||||
- gem --version
|
||||
- gem install bundler -v 1.17.3
|
||||
- bundler --version
|
||||
- bundle platform
|
||||
- bundle install --path=vendor/bundle --retry=3 --jobs=3
|
||||
|
||||
test_script:
|
||||
- bundle exec rake test
|
||||
|
||||
build: off
|
||||
version: 1.0.{build}-{branch}
|
||||
|
||||
skip_tags: true
|
||||
|
||||
cache:
|
||||
- vendor/bundle
|
||||
|
||||
test_script:
|
||||
- true
|
||||
|
||||
build: off
|
||||
|
||||
171
bin/bench
171
bin/bench
@ -1,171 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
# ActiveModelSerializers Benchmark driver
|
||||
# Adapted from
|
||||
# https://github.com/ruby-bench/ruby-bench-suite/blob/8ad567f7e43a044ae48c36833218423bb1e2bd9d/rails/benchmarks/driver.rb
|
||||
require 'bundler'
|
||||
Bundler.setup
|
||||
require 'json'
|
||||
require 'pathname'
|
||||
require 'optparse'
|
||||
require 'digest'
|
||||
require 'pathname'
|
||||
require 'shellwords'
|
||||
require 'logger'
|
||||
require 'English'
|
||||
|
||||
class BenchmarkDriver
|
||||
ROOT = Pathname File.expand_path(File.join('..', '..'), __FILE__)
|
||||
BASE = ENV.fetch('BASE') { ROOT.join('test', 'benchmark') }
|
||||
ESCAPED_BASE = Shellwords.shellescape(BASE)
|
||||
|
||||
def self.benchmark(options)
|
||||
new(options).run
|
||||
end
|
||||
|
||||
def self.parse_argv_and_run(argv = ARGV, options = {})
|
||||
options = {
|
||||
repeat_count: 1,
|
||||
pattern: [],
|
||||
env: 'CACHE_ON=on'
|
||||
}.merge!(options)
|
||||
|
||||
OptionParser.new do |opts|
|
||||
opts.banner = 'Usage: bin/bench [options]'
|
||||
|
||||
opts.on('-r', '--repeat-count [NUM]', 'Run benchmarks [NUM] times taking the best result') do |value|
|
||||
options[:repeat_count] = value.to_i
|
||||
end
|
||||
|
||||
opts.on('-p', '--pattern <PATTERN1,PATTERN2,PATTERN3>', 'Benchmark name pattern') do |value|
|
||||
options[:pattern] = value.split(',')
|
||||
end
|
||||
|
||||
opts.on('-e', '--env <var1=val1,var2=val2,var3=vale>', 'ENV variables to pass in') do |value|
|
||||
options[:env] = value.split(',')
|
||||
end
|
||||
end.parse!(argv)
|
||||
|
||||
benchmark(options)
|
||||
end
|
||||
|
||||
attr_reader :commit_hash, :base
|
||||
|
||||
# Based on logfmt:
|
||||
# https://www.brandur.org/logfmt
|
||||
# For more complete implementation see:
|
||||
# see https://github.com/arachnid-cb/logfmtr/blob/master/lib/logfmtr/base.rb
|
||||
# For usage see:
|
||||
# https://blog.codeship.com/logfmt-a-log-format-thats-easy-to-read-and-write/
|
||||
# https://engineering.heroku.com/blogs/2014-09-05-hutils-explore-your-structured-data-logs/
|
||||
# For Ruby parser see:
|
||||
# https://github.com/cyberdelia/logfmt-ruby
|
||||
def self.summary_logger(device = 'output.txt')
|
||||
require 'time'
|
||||
logger = Logger.new(device)
|
||||
logger.level = Logger::INFO
|
||||
logger.formatter = proc { |severity, datetime, progname, msg|
|
||||
msg = "'#{msg}'"
|
||||
"level=#{severity} time=#{datetime.utc.iso8601(6)} pid=#{Process.pid} progname=#{progname} msg=#{msg}#{$INPUT_RECORD_SEPARATOR}"
|
||||
}
|
||||
logger
|
||||
end
|
||||
|
||||
def self.stdout_logger
|
||||
logger = Logger.new(STDOUT)
|
||||
logger.level = Logger::INFO
|
||||
logger.formatter = proc { |_, _, _, msg| "#{msg}#{$INPUT_RECORD_SEPARATOR}" }
|
||||
logger
|
||||
end
|
||||
|
||||
def initialize(options)
|
||||
@writer = ENV['SUMMARIZE'] ? self.class.summary_logger : self.class.stdout_logger
|
||||
@repeat_count = options[:repeat_count]
|
||||
@pattern = options[:pattern]
|
||||
@commit_hash = options.fetch(:commit_hash) { `git rev-parse --short HEAD`.chomp }
|
||||
@base = options.fetch(:base) { ESCAPED_BASE }
|
||||
@env = Array(options[:env]).join(' ')
|
||||
@rubyopt = options[:rubyopt] # TODO: rename
|
||||
end
|
||||
|
||||
def run
|
||||
files.each do |path|
|
||||
next if !@pattern.empty? && /#{@pattern.join('|')}/ !~ File.basename(path)
|
||||
run_single(Shellwords.shellescape(path))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def files
|
||||
Dir[File.join(base, 'bm_*')]
|
||||
end
|
||||
|
||||
def run_single(path)
|
||||
script = "RAILS_ENV=production #{@env} ruby #{@rubyopt} #{path}"
|
||||
environment = `ruby -v`.chomp.strip[/\d+\.\d+\.\d+\w+/]
|
||||
|
||||
runs_output = measure(script)
|
||||
if runs_output.empty?
|
||||
results = { error: :no_results }
|
||||
return
|
||||
end
|
||||
|
||||
results = {}
|
||||
results['commit_hash'] = commit_hash
|
||||
results['version'] = runs_output.first['version']
|
||||
results['rails_version'] = runs_output.first['rails_version']
|
||||
results['benchmark_run[environment]'] = environment
|
||||
results['runs'] = []
|
||||
|
||||
runs_output.each do |output|
|
||||
results['runs'] << {
|
||||
'benchmark_type[category]' => output['label'],
|
||||
'benchmark_run[result][iterations_per_second]' => output['iterations_per_second'].round(3),
|
||||
'benchmark_run[result][total_allocated_objects_per_iteration]' => output['total_allocated_objects_per_iteration']
|
||||
}
|
||||
end
|
||||
ensure
|
||||
results && report(results)
|
||||
end
|
||||
|
||||
def report(results)
|
||||
@writer.info { 'Benchmark results:' }
|
||||
@writer.info { JSON.pretty_generate(results) }
|
||||
end
|
||||
|
||||
def summarize(result)
|
||||
puts "#{result['label']} #{result['iterations_per_second']}/ips; #{result['total_allocated_objects_per_iteration']} objects"
|
||||
end
|
||||
|
||||
# FIXME: ` provides the full output but it'll return failed output as well.
|
||||
def measure(script)
|
||||
results = Hash.new { |h, k| h[k] = [] }
|
||||
|
||||
@repeat_count.times do
|
||||
output = sh(script)
|
||||
output.each_line do |line|
|
||||
next if line.nil?
|
||||
begin
|
||||
result = JSON.parse(line)
|
||||
rescue JSON::ParserError
|
||||
result = { error: line } # rubocop:disable Lint/UselessAssignment
|
||||
else
|
||||
summarize(result)
|
||||
results[result['label']] << result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
results.map do |_, bm_runs|
|
||||
bm_runs.sort_by do |run|
|
||||
run['iterations_per_second']
|
||||
end.last
|
||||
end
|
||||
end
|
||||
|
||||
def sh(cmd)
|
||||
`#{cmd}`
|
||||
end
|
||||
end
|
||||
|
||||
BenchmarkDriver.parse_argv_and_run if $PROGRAM_NAME == __FILE__
|
||||
15
docs/rfcs/template.md
Normal file
15
docs/rfcs/template.md
Normal file
@ -0,0 +1,15 @@
|
||||
- Start Date: (YYYY-MM-DD)
|
||||
- RFC PR: https://github.com/rails-api/active_model_serializers/pull/dddd
|
||||
- ActiveModelSerializers Issue: https://github.com/rails-api/active_model_serializers/issues/dddd
|
||||
|
||||
# Summary
|
||||
|
||||
# Motivation
|
||||
|
||||
# Detailed design
|
||||
|
||||
# Drawbacks
|
||||
|
||||
# Alternatives
|
||||
|
||||
# Unresolved questions
|
||||
@ -1,107 +0,0 @@
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
|
||||
module ActionController
|
||||
# Action Controller Serialization
|
||||
#
|
||||
# Overrides render :json to check if the given object implements +active_model_serializer+
|
||||
# as a method. If so, use the returned serializer instead of calling +to_json+ on the object.
|
||||
#
|
||||
# This module also provides a serialization_scope method that allows you to configure the
|
||||
# +serialization_scope+ of the serializer. Most apps will likely set the +serialization_scope+
|
||||
# to the current user:
|
||||
#
|
||||
# class ApplicationController < ActionController::Base
|
||||
# serialization_scope :current_user
|
||||
# end
|
||||
#
|
||||
# If you need more complex scope rules, you can simply override the serialization_scope:
|
||||
#
|
||||
# class ApplicationController < ActionController::Base
|
||||
# private
|
||||
#
|
||||
# def serialization_scope
|
||||
# current_user
|
||||
# end
|
||||
# end
|
||||
#
|
||||
module Serialization
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
include ActionController::Renderers
|
||||
|
||||
class << self
|
||||
attr_accessor :enabled
|
||||
end
|
||||
self.enabled = true
|
||||
|
||||
included do
|
||||
class_attribute :_serialization_scope
|
||||
self._serialization_scope = :current_user
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def serialization_scope(scope)
|
||||
self._serialization_scope = scope
|
||||
end
|
||||
end
|
||||
|
||||
[:_render_option_json, :_render_with_renderer_json].each do |renderer_method|
|
||||
define_method renderer_method do |resource, options|
|
||||
serializer = build_json_serializer(resource, options)
|
||||
|
||||
if serializer
|
||||
super(serializer, options)
|
||||
else
|
||||
super(resource, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def namespace_for_serializer
|
||||
@namespace_for_serializer ||= namespace_for_class(self.class) unless namespace_for_class(self.class) == Object
|
||||
end
|
||||
|
||||
def namespace_for_class(klass)
|
||||
if Module.method_defined?(:module_parent)
|
||||
klass.module_parent
|
||||
else
|
||||
klass.parent
|
||||
end
|
||||
end
|
||||
|
||||
def default_serializer(resource)
|
||||
options = {}.tap do |o|
|
||||
o[:namespace] = namespace_for_serializer if namespace_for_serializer
|
||||
end
|
||||
|
||||
ActiveModel::Serializer.serializer_for(resource, options)
|
||||
end
|
||||
|
||||
def default_serializer_options
|
||||
{}
|
||||
end
|
||||
|
||||
def serialization_scope
|
||||
_serialization_scope = self.class._serialization_scope
|
||||
send(_serialization_scope) if _serialization_scope && respond_to?(_serialization_scope, true)
|
||||
end
|
||||
|
||||
def build_json_serializer(resource, options = {})
|
||||
options = default_serializer_options.merge(options)
|
||||
@namespace_for_serializer = options.fetch(:namespace, nil)
|
||||
|
||||
if serializer = options.fetch(:serializer, default_serializer(resource))
|
||||
options[:scope] = serialization_scope unless options.has_key?(:scope)
|
||||
|
||||
if resource.respond_to?(:to_ary)
|
||||
options[:resource_name] = controller_name
|
||||
options[:namespace] = namespace_for_serializer if namespace_for_serializer
|
||||
end
|
||||
|
||||
serializer.new(resource, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,79 +0,0 @@
|
||||
module ActionController
|
||||
module SerializationAssertions
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
setup :setup_serialization_subscriptions
|
||||
teardown :teardown_serialization_subscriptions
|
||||
end
|
||||
|
||||
def setup_serialization_subscriptions
|
||||
@serializers = Hash.new(0)
|
||||
|
||||
ActiveSupport::Notifications.subscribe("!serialize.active_model_serializers") do |name, start, finish, id, payload|
|
||||
serializer = payload[:serializer]
|
||||
@serializers[serializer] += 1
|
||||
end
|
||||
end
|
||||
|
||||
def teardown_serialization_subscriptions
|
||||
ActiveSupport::Notifications.unsubscribe("!serialize.active_model_serializers")
|
||||
end
|
||||
|
||||
def process(*args)
|
||||
@serializers = Hash.new(0)
|
||||
super
|
||||
end
|
||||
|
||||
# Asserts that the request was rendered with the appropriate serializers.
|
||||
#
|
||||
# # assert that the "PostSerializer" serializer was rendered
|
||||
# assert_serializer "PostSerializer"
|
||||
#
|
||||
# # assert that the instance of PostSerializer was rendered
|
||||
# assert_serializer PostSerializer
|
||||
#
|
||||
# # assert that the "PostSerializer" serializer was rendered
|
||||
# assert_serializer :post_serializer
|
||||
#
|
||||
# # assert that the rendered serializer starts with "Post"
|
||||
# assert_serializer %r{\APost.+\Z}
|
||||
#
|
||||
# # assert that no serializer was rendered
|
||||
# assert_serializer nil
|
||||
#
|
||||
#
|
||||
def assert_serializer(options = {}, message = nil)
|
||||
# Force body to be read in case the template is being streamed.
|
||||
response.body
|
||||
|
||||
rendered = @serializers
|
||||
msg = message || "expecting <#{options.inspect}> but rendering with <#{rendered.keys}>"
|
||||
|
||||
matches_serializer = case options
|
||||
when lambda { |options| options.kind_of?(Class) && options < ActiveModel::Serializer }
|
||||
rendered.any? do |serializer, count|
|
||||
options.name == serializer
|
||||
end
|
||||
when Symbol
|
||||
options = options.to_s.camelize
|
||||
rendered.any? do |serializer, count|
|
||||
serializer == options
|
||||
end
|
||||
when String
|
||||
!options.empty? && rendered.any? do |serializer, count|
|
||||
serializer == options
|
||||
end
|
||||
when Regexp
|
||||
rendered.any? do |serializer, count|
|
||||
serializer.match(options)
|
||||
end
|
||||
when NilClass
|
||||
rendered.blank?
|
||||
else
|
||||
raise ArgumentError, "assert_serializer only accepts a String, Symbol, Regexp, ActiveModel::Serializer, or nil"
|
||||
end
|
||||
assert matches_serializer, msg
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,68 +0,0 @@
|
||||
require 'active_model/default_serializer'
|
||||
require 'active_model/serializable'
|
||||
|
||||
module ActiveModel
|
||||
class ArraySerializer
|
||||
include Serializable
|
||||
|
||||
class << self
|
||||
attr_accessor :_root
|
||||
alias root _root=
|
||||
alias root= _root=
|
||||
end
|
||||
|
||||
def initialize(object, options={})
|
||||
@object = object
|
||||
@scope = options[:scope]
|
||||
@root = options.fetch(:root, self.class._root)
|
||||
@polymorphic = options.fetch(:polymorphic, false)
|
||||
@meta_key = options[:meta_key] || :meta
|
||||
@meta = options[@meta_key]
|
||||
@each_serializer = options[:each_serializer]
|
||||
@resource_name = options[:resource_name]
|
||||
@only = options[:only] ? Array(options[:only]) : nil
|
||||
@except = options[:except] ? Array(options[:except]) : nil
|
||||
@context = options[:context]
|
||||
@namespace = options[:namespace]
|
||||
@key_format = options[:key_format] || options[:each_serializer].try(:key_format)
|
||||
end
|
||||
attr_accessor :object, :scope, :root, :meta_key, :meta, :key_format, :context
|
||||
|
||||
def json_key
|
||||
key = root.nil? ? @resource_name : root
|
||||
|
||||
key_format == :lower_camel && key.present? ? key.camelize(:lower) : key
|
||||
end
|
||||
|
||||
def serializer_for(item)
|
||||
serializer_class = @each_serializer || Serializer.serializer_for(item, namespace: @namespace) || DefaultSerializer
|
||||
serializer_class.new(item, scope: scope, key_format: key_format, context: @context, only: @only, except: @except, polymorphic: @polymorphic, namespace: @namespace)
|
||||
end
|
||||
|
||||
def serializable_object(options={})
|
||||
@object.map do |item|
|
||||
serializer_for(item).serializable_object_with_notification(options)
|
||||
end
|
||||
end
|
||||
alias_method :serializable_array, :serializable_object
|
||||
|
||||
def embedded_in_root_associations
|
||||
@object.each_with_object({}) do |item, hash|
|
||||
serializer_for(item).embedded_in_root_associations.each_pair do |type, objects|
|
||||
next if !objects || objects.flatten.empty?
|
||||
|
||||
if hash.has_key?(type)
|
||||
case hash[type] when Hash
|
||||
hash[type].deep_merge!(objects){ |key, old, new| (Array(old) + Array(new)).uniq }
|
||||
else
|
||||
hash[type].concat(objects).uniq!
|
||||
end
|
||||
else
|
||||
hash[type] = objects
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@ -1,28 +0,0 @@
|
||||
require 'active_model/serializable'
|
||||
|
||||
module ActiveModel
|
||||
# DefaultSerializer
|
||||
#
|
||||
# Provides a constant interface for all items
|
||||
class DefaultSerializer
|
||||
include ActiveModel::Serializable
|
||||
|
||||
attr_reader :object
|
||||
|
||||
def initialize(object, options={})
|
||||
@object = object
|
||||
@wrap_in_array = options[:_wrap_in_array]
|
||||
end
|
||||
|
||||
def as_json(options={})
|
||||
instrument do
|
||||
return [] if @object.nil? && @wrap_in_array
|
||||
hash = @object.as_json
|
||||
@wrap_in_array ? [hash] : hash
|
||||
end
|
||||
end
|
||||
|
||||
alias serializable_hash as_json
|
||||
alias serializable_object as_json
|
||||
end
|
||||
end
|
||||
@ -1,59 +0,0 @@
|
||||
require 'active_model/serializable/utils'
|
||||
|
||||
module ActiveModel
|
||||
module Serializable
|
||||
INSTRUMENTATION_KEY = '!serialize.active_model_serializers'.freeze
|
||||
|
||||
def self.included(base)
|
||||
base.extend Utils
|
||||
end
|
||||
|
||||
def as_json(options={})
|
||||
instrument do
|
||||
if root = options.fetch(:root, json_key)
|
||||
hash = { root => serializable_object(options) }
|
||||
hash.merge!(serializable_data)
|
||||
hash
|
||||
else
|
||||
serializable_object(options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def serializable_object_with_notification(options={})
|
||||
instrument { serializable_object(options) }
|
||||
end
|
||||
|
||||
def serializable_data
|
||||
embedded_in_root_associations.tap do |hash|
|
||||
if respond_to?(:meta) && meta
|
||||
hash[meta_key] = meta
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def namespace
|
||||
if module_name = get_namespace
|
||||
Serializer.serializers_cache.fetch_or_store(module_name) do
|
||||
Utils._const_get(module_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def embedded_in_root_associations
|
||||
{}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_namespace
|
||||
modules = self.class.name.split('::')
|
||||
modules[0..-2].join('::') if modules.size > 1
|
||||
end
|
||||
|
||||
def instrument(&block)
|
||||
payload = { serializer: self.class.name }
|
||||
ActiveSupport::Notifications.instrument(INSTRUMENTATION_KEY, payload, &block)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,16 +0,0 @@
|
||||
module ActiveModel
|
||||
module Serializable
|
||||
module Utils
|
||||
extend self
|
||||
|
||||
def _const_get(const)
|
||||
begin
|
||||
method = RUBY_VERSION >= '2.0' ? :const_get : :qualified_const_get
|
||||
Object.send method, const
|
||||
rescue NameError
|
||||
const.safe_constantize
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,318 +0,0 @@
|
||||
require 'active_model/array_serializer'
|
||||
require 'active_model/serializable'
|
||||
require 'active_model/serializer/association'
|
||||
require 'active_model/serializer/config'
|
||||
|
||||
require 'thread'
|
||||
require 'concurrent/map'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
include Serializable
|
||||
|
||||
@mutex = Mutex.new
|
||||
|
||||
class << self
|
||||
def inherited(base)
|
||||
base._root = _root
|
||||
base._attributes = (_attributes || []).dup
|
||||
base._associations = (_associations || {}).dup
|
||||
end
|
||||
|
||||
def setup
|
||||
@mutex.synchronize do
|
||||
yield CONFIG
|
||||
end
|
||||
end
|
||||
|
||||
EMBED_IN_ROOT_OPTIONS = [
|
||||
:include,
|
||||
:embed_in_root,
|
||||
:embed_in_root_key,
|
||||
:embed_namespace
|
||||
].freeze
|
||||
|
||||
def embed(type, options={})
|
||||
CONFIG.embed = type
|
||||
if EMBED_IN_ROOT_OPTIONS.any? { |opt| options[opt].present? }
|
||||
CONFIG.embed_in_root = true
|
||||
end
|
||||
if options[:embed_in_root_key].present?
|
||||
CONFIG.embed_in_root_key = options[:embed_in_root_key]
|
||||
end
|
||||
ActiveSupport::Deprecation.warn <<-WARN
|
||||
** Notice: embed is deprecated. **
|
||||
The use of .embed method on a Serializer will be soon removed, as this should have a global scope and not a class scope.
|
||||
Please use the global .setup method instead:
|
||||
ActiveModel::Serializer.setup do |config|
|
||||
config.embed = :#{type}
|
||||
config.embed_in_root = #{CONFIG.embed_in_root || false}
|
||||
end
|
||||
WARN
|
||||
end
|
||||
|
||||
def format_keys(format)
|
||||
@key_format = format
|
||||
end
|
||||
attr_reader :key_format
|
||||
|
||||
def serializer_for(resource, options = {})
|
||||
if resource.respond_to?(:serializer_class)
|
||||
resource.serializer_class
|
||||
elsif resource.respond_to?(:to_ary)
|
||||
if Object.constants.include?(:ArraySerializer)
|
||||
::ArraySerializer
|
||||
else
|
||||
ArraySerializer
|
||||
end
|
||||
else
|
||||
klass_name = build_serializer_class(resource, options)
|
||||
Serializer.serializers_cache.fetch_or_store(klass_name) do
|
||||
_const_get(klass_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
attr_accessor :_root, :_attributes, :_associations
|
||||
alias root _root=
|
||||
alias root= _root=
|
||||
|
||||
def root_name
|
||||
if name
|
||||
root_name = name.demodulize.underscore.sub(/_serializer$/, '')
|
||||
CONFIG.plural_default_root ? root_name.pluralize : root_name
|
||||
end
|
||||
end
|
||||
|
||||
def attributes(*attrs)
|
||||
attrs.each do |attr|
|
||||
striped_attr = strip_attribute attr
|
||||
|
||||
@_attributes << striped_attr
|
||||
|
||||
define_method striped_attr do
|
||||
object.read_attribute_for_serialization attr
|
||||
end unless method_defined?(attr)
|
||||
end
|
||||
end
|
||||
|
||||
def has_one(*attrs)
|
||||
associate(Association::HasOne, *attrs)
|
||||
end
|
||||
|
||||
def has_many(*attrs)
|
||||
associate(Association::HasMany, *attrs)
|
||||
end
|
||||
|
||||
def serializers_cache
|
||||
@serializers_cache ||= Concurrent::Map.new
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def strip_attribute(attr)
|
||||
symbolized = attr.is_a?(Symbol)
|
||||
|
||||
attr = attr.to_s.gsub(/\?\Z/, '')
|
||||
attr = attr.to_sym if symbolized
|
||||
attr
|
||||
end
|
||||
|
||||
def build_serializer_class(resource, options)
|
||||
"".tap do |klass_name|
|
||||
klass_name << "#{options[:namespace]}::" if options[:namespace]
|
||||
klass_name << options[:prefix].to_s.classify if options[:prefix]
|
||||
klass_name << "#{resource.class.name}Serializer"
|
||||
end
|
||||
end
|
||||
|
||||
def associate(klass, *attrs)
|
||||
options = attrs.extract_options!
|
||||
|
||||
attrs.each do |attr|
|
||||
define_method attr do
|
||||
object.send attr
|
||||
end unless method_defined?(attr)
|
||||
|
||||
@_associations[attr] = klass.new(attr, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(object, options={})
|
||||
@object = object
|
||||
@scope = options[:scope]
|
||||
@root = options.fetch(:root, self.class._root)
|
||||
@polymorphic = options.fetch(:polymorphic, false)
|
||||
@meta_key = options[:meta_key] || :meta
|
||||
@meta = options[@meta_key]
|
||||
@wrap_in_array = options[:_wrap_in_array]
|
||||
@only = options[:only] ? Array(options[:only]) : nil
|
||||
@except = options[:except] ? Array(options[:except]) : nil
|
||||
@key_format = options[:key_format]
|
||||
@context = options[:context]
|
||||
@namespace = options[:namespace]
|
||||
end
|
||||
attr_accessor :object, :scope, :root, :meta_key, :meta, :key_format, :context, :polymorphic
|
||||
|
||||
def json_key
|
||||
key = if root == true || root.nil?
|
||||
self.class.root_name
|
||||
else
|
||||
root
|
||||
end
|
||||
|
||||
key_format == :lower_camel && key.present? ? key.camelize(:lower) : key
|
||||
end
|
||||
|
||||
def attributes
|
||||
filter(self.class._attributes.dup).each_with_object({}) do |name, hash|
|
||||
hash[name] = send(name)
|
||||
end
|
||||
end
|
||||
|
||||
def associations(options={})
|
||||
associations = self.class._associations
|
||||
included_associations = filter(associations.keys)
|
||||
associations.each_with_object({}) do |(name, association), hash|
|
||||
if included_associations.include? name
|
||||
if association.embed_ids?
|
||||
ids = serialize_ids association
|
||||
if association.embed_namespace?
|
||||
hash = hash[association.embed_namespace] ||= {}
|
||||
hash[association.key] = ids
|
||||
else
|
||||
hash[association.key] = ids
|
||||
end
|
||||
elsif association.embed_objects?
|
||||
if association.embed_namespace?
|
||||
hash = hash[association.embed_namespace] ||= {}
|
||||
end
|
||||
hash[association.embedded_key] = serialize association, options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def filter(keys)
|
||||
if @only
|
||||
keys & @only
|
||||
elsif @except
|
||||
keys - @except
|
||||
else
|
||||
keys
|
||||
end
|
||||
end
|
||||
|
||||
def embedded_in_root_associations
|
||||
associations = self.class._associations
|
||||
included_associations = filter(associations.keys)
|
||||
associations.each_with_object({}) do |(name, association), hash|
|
||||
if included_associations.include? name
|
||||
association_serializer = build_serializer(association)
|
||||
# we must do this always because even if the current association is not
|
||||
# embedded in root, it might have its own associations that are embedded in root
|
||||
hash.merge!(association_serializer.embedded_in_root_associations) do |key, oldval, newval|
|
||||
if oldval.respond_to?(:to_ary)
|
||||
[oldval, newval].flatten.uniq
|
||||
else
|
||||
oldval.merge(newval) { |_, oldval, newval| [oldval, newval].flatten.uniq }
|
||||
end
|
||||
end
|
||||
|
||||
if association.embed_in_root?
|
||||
if association.embed_in_root_key?
|
||||
hash = hash[association.embed_in_root_key] ||= {}
|
||||
end
|
||||
|
||||
serialized_data = association_serializer.serializable_object
|
||||
key = association.root_key
|
||||
if hash.has_key?(key)
|
||||
hash[key].concat(serialized_data).uniq!
|
||||
else
|
||||
hash[key] = serialized_data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def build_serializer(association)
|
||||
object = send(association.name)
|
||||
association.build_serializer(object, association_options_for_serializer(association))
|
||||
end
|
||||
|
||||
def association_options_for_serializer(association)
|
||||
prefix = association.options[:prefix]
|
||||
namespace = association.options[:namespace] || @namespace || self.namespace
|
||||
|
||||
{ scope: scope }.tap do |opts|
|
||||
opts[:namespace] = namespace if namespace
|
||||
opts[:prefix] = prefix if prefix
|
||||
end
|
||||
end
|
||||
|
||||
def serialize(association,options={})
|
||||
build_serializer(association).serializable_object(options)
|
||||
end
|
||||
|
||||
def serialize_ids(association)
|
||||
associated_data = send(association.name)
|
||||
if associated_data.respond_to?(:to_ary)
|
||||
associated_data.map { |elem| serialize_id(elem, association) }
|
||||
else
|
||||
serialize_id(associated_data, association) if associated_data
|
||||
end
|
||||
end
|
||||
|
||||
def key_format
|
||||
@key_format || self.class.key_format || CONFIG.key_format
|
||||
end
|
||||
|
||||
def format_key(key)
|
||||
if key_format == :lower_camel
|
||||
key.to_s.camelize(:lower)
|
||||
else
|
||||
key
|
||||
end
|
||||
end
|
||||
|
||||
def convert_keys(hash)
|
||||
Hash[hash.map do |k,v|
|
||||
key = if k.is_a?(Symbol)
|
||||
format_key(k).to_sym
|
||||
else
|
||||
format_key(k)
|
||||
end
|
||||
|
||||
[key ,v]
|
||||
end]
|
||||
end
|
||||
|
||||
attr_writer :serialization_options
|
||||
def serialization_options
|
||||
@serialization_options || {}
|
||||
end
|
||||
|
||||
def serializable_object(options={})
|
||||
self.serialization_options = options
|
||||
return @wrap_in_array ? [] : nil if @object.nil?
|
||||
hash = attributes
|
||||
hash.merge! associations(options)
|
||||
hash = convert_keys(hash) if key_format.present?
|
||||
hash = { :type => type_name(@object), type_name(@object) => hash } if @polymorphic
|
||||
@wrap_in_array ? [hash] : hash
|
||||
end
|
||||
alias_method :serializable_hash, :serializable_object
|
||||
|
||||
def serialize_id(elem, association)
|
||||
id = elem.read_attribute_for_serialization(association.embed_key)
|
||||
association.polymorphic? ? { id: id, type: type_name(elem) } : id
|
||||
end
|
||||
|
||||
def type_name(elem)
|
||||
elem.class.to_s.demodulize.underscore.to_sym
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@ -1,58 +0,0 @@
|
||||
require 'active_model/default_serializer'
|
||||
require 'active_model/serializer/association/has_one'
|
||||
require 'active_model/serializer/association/has_many'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class Association
|
||||
def initialize(name, options={})
|
||||
if options.has_key?(:include)
|
||||
ActiveSupport::Deprecation.warn <<-WARN
|
||||
** Notice: include was renamed to embed_in_root. **
|
||||
WARN
|
||||
end
|
||||
|
||||
@name = name.to_s
|
||||
@options = options
|
||||
self.embed = options.fetch(:embed) { CONFIG.embed }
|
||||
@polymorphic = options.fetch(:polymorphic, false)
|
||||
@embed_in_root = options.fetch(:embed_in_root) { options.fetch(:include) { CONFIG.embed_in_root } }
|
||||
@key_format = options.fetch(:key_format) { CONFIG.key_format }
|
||||
@embed_key = options[:embed_key] || :id
|
||||
@key = options[:key]
|
||||
@embedded_key = options[:root] || name
|
||||
@embed_in_root_key = options.fetch(:embed_in_root_key) { CONFIG.embed_in_root_key }
|
||||
@embed_namespace = options.fetch(:embed_namespace) { CONFIG.embed_namespace }
|
||||
|
||||
serializer = @options[:serializer]
|
||||
@serializer_from_options = serializer.is_a?(String) ? serializer.constantize : serializer
|
||||
end
|
||||
|
||||
attr_reader :name, :embed_ids, :embed_objects, :polymorphic
|
||||
attr_accessor :embed_in_root, :embed_key, :key, :embedded_key, :root_key, :serializer_from_options, :options, :key_format, :embed_in_root_key, :embed_namespace
|
||||
alias embed_ids? embed_ids
|
||||
alias embed_objects? embed_objects
|
||||
alias embed_in_root? embed_in_root
|
||||
alias embed_in_root_key? embed_in_root_key
|
||||
alias embed_namespace? embed_namespace
|
||||
alias polymorphic? polymorphic
|
||||
|
||||
def embed=(embed)
|
||||
@embed_ids = embed == :id || embed == :ids
|
||||
@embed_objects = embed == :object || embed == :objects
|
||||
end
|
||||
|
||||
def serializer_from_object(object, options = {})
|
||||
Serializer.serializer_for(object, options)
|
||||
end
|
||||
|
||||
def default_serializer
|
||||
DefaultSerializer
|
||||
end
|
||||
|
||||
def build_serializer(object, options = {})
|
||||
serializer_class(object, options).new(object, options.merge(self.options))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,39 +0,0 @@
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class Association
|
||||
class HasMany < Association
|
||||
def initialize(name, *args)
|
||||
super
|
||||
@root_key = @embedded_key.to_s
|
||||
@key ||= case CONFIG.default_key_type
|
||||
when :name then name.to_s.pluralize
|
||||
else "#{name.to_s.singularize}_ids"
|
||||
end
|
||||
end
|
||||
|
||||
def serializer_class(object, _)
|
||||
if use_array_serializer?
|
||||
ArraySerializer
|
||||
else
|
||||
serializer_from_options
|
||||
end
|
||||
end
|
||||
|
||||
def options
|
||||
if use_array_serializer?
|
||||
{ each_serializer: serializer_from_options }.merge! super
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def use_array_serializer?
|
||||
!serializer_from_options ||
|
||||
serializer_from_options && !(serializer_from_options <= ArraySerializer)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,25 +0,0 @@
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class Association
|
||||
class HasOne < Association
|
||||
def initialize(name, *args)
|
||||
super
|
||||
@root_key = @embedded_key.to_s.pluralize
|
||||
@key ||= case CONFIG.default_key_type
|
||||
when :name then name.to_s.singularize
|
||||
else "#{name}_id"
|
||||
end
|
||||
end
|
||||
|
||||
def serializer_class(object, options = {})
|
||||
(serializer_from_options unless object.nil?) || serializer_from_object(object, options) || default_serializer
|
||||
end
|
||||
|
||||
def build_serializer(object, options = {})
|
||||
options[:_wrap_in_array] = embed_in_root?
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,31 +0,0 @@
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class Config
|
||||
def initialize(data = {})
|
||||
@data = data
|
||||
end
|
||||
|
||||
def each(&block)
|
||||
@data.each(&block)
|
||||
end
|
||||
|
||||
def clear
|
||||
@data.clear
|
||||
end
|
||||
|
||||
def method_missing(name, *args)
|
||||
name = name.to_s
|
||||
return @data[name] if @data.include?(name)
|
||||
match = name.match(/\A(.*?)([?=]?)\Z/)
|
||||
case match[2]
|
||||
when "="
|
||||
@data[match[1]] = args.first
|
||||
when "?"
|
||||
!!@data[match[1]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
CONFIG = Config.new('embed' => :objects) # :nodoc:
|
||||
end
|
||||
end
|
||||
@ -1,13 +0,0 @@
|
||||
require 'rails/generators'
|
||||
require 'rails/generators/rails/resource/resource_generator'
|
||||
|
||||
module Rails
|
||||
module Generators
|
||||
class ResourceGenerator
|
||||
def add_serializer
|
||||
invoke 'serializer'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
Description:
|
||||
Generates a serializer for the given resource with tests.
|
||||
|
||||
Example:
|
||||
`rails generate serializer Account name created_at`
|
||||
|
||||
For TestUnit it creates:
|
||||
Serializer: app/serializers/account_serializer.rb
|
||||
TestUnit: test/unit/account_serializer_test.rb
|
||||
@ -1,14 +0,0 @@
|
||||
require 'rails/generators'
|
||||
require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
|
||||
|
||||
module Rails
|
||||
module Generators
|
||||
class ScaffoldControllerGenerator
|
||||
if Rails::VERSION::MAJOR >= 4
|
||||
source_root File.expand_path('../templates', __FILE__)
|
||||
|
||||
hook_for :serializer, default: true, type: :boolean
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,37 +0,0 @@
|
||||
module Rails
|
||||
module Generators
|
||||
class SerializerGenerator < NamedBase
|
||||
source_root File.expand_path('../templates', __FILE__)
|
||||
check_class_collision suffix: 'Serializer'
|
||||
|
||||
argument :attributes, type: :array, default: [], banner: 'field:type field:type'
|
||||
|
||||
class_option :parent, type: :string, desc: 'The parent class for the generated serializer'
|
||||
|
||||
def create_serializer_file
|
||||
template 'serializer.rb', File.join('app/serializers', class_path, "#{file_name}_serializer.rb")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def attributes_names
|
||||
[:id] + attributes.select { |attr| !attr.reference? }.map { |a| a.name.to_sym }
|
||||
end
|
||||
|
||||
def association_names
|
||||
attributes.select { |attr| attr.reference? }.map { |a| a.name.to_sym }
|
||||
end
|
||||
|
||||
def parent_class_name
|
||||
if options[:parent]
|
||||
options[:parent]
|
||||
elsif (ns = Rails::Generators.namespace) && ns.const_defined?(:ApplicationSerializer) ||
|
||||
(Object.const_get(:ApplicationSerializer) rescue nil)
|
||||
'ApplicationSerializer'
|
||||
else
|
||||
'ActiveModel::Serializer'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,93 +0,0 @@
|
||||
<% if namespaced? -%>
|
||||
require_dependency "<%= namespaced_file_path %>/application_controller"
|
||||
|
||||
<% end -%>
|
||||
<% module_namespacing do -%>
|
||||
class <%= controller_class_name %>Controller < ApplicationController
|
||||
before_action :set_<%= singular_table_name %>, only: [:show, :edit, :update, :destroy]
|
||||
|
||||
# GET <%= route_url %>
|
||||
# GET <%= route_url %>.json
|
||||
def index
|
||||
@<%= plural_table_name %> = <%= orm_class.all(class_name) %>
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: <%= "@#{plural_table_name}" %> }
|
||||
end
|
||||
end
|
||||
|
||||
# GET <%= route_url %>/1
|
||||
# GET <%= route_url %>/1.json
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render json: <%= "@#{singular_table_name}" %> }
|
||||
end
|
||||
end
|
||||
|
||||
# GET <%= route_url %>/new
|
||||
def new
|
||||
@<%= singular_table_name %> = <%= orm_class.build(class_name) %>
|
||||
end
|
||||
|
||||
# GET <%= route_url %>/1/edit
|
||||
def edit
|
||||
end
|
||||
|
||||
# POST <%= route_url %>
|
||||
# POST <%= route_url %>.json
|
||||
def create
|
||||
@<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>
|
||||
|
||||
respond_to do |format|
|
||||
if @<%= orm_instance.save %>
|
||||
format.html { redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully created.'" %> }
|
||||
format.json { render json: <%= "@#{singular_table_name}" %>, status: :created }
|
||||
else
|
||||
format.html { render action: 'new' }
|
||||
format.json { render json: <%= "@#{orm_instance.errors}" %>, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PATCH/PUT <%= route_url %>/1
|
||||
# PATCH/PUT <%= route_url %>/1.json
|
||||
def update
|
||||
respond_to do |format|
|
||||
if @<%= orm_instance.update("#{singular_table_name}_params") %>
|
||||
format.html { redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully updated.'" %> }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.html { render action: 'edit' }
|
||||
format.json { render json: <%= "@#{orm_instance.errors}" %>, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE <%= route_url %>/1
|
||||
# DELETE <%= route_url %>/1.json
|
||||
def destroy
|
||||
@<%= orm_instance.destroy %>
|
||||
respond_to do |format|
|
||||
format.html { redirect_to <%= index_helper %>_url }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
# Use callbacks to share common setup or constraints between actions.
|
||||
def set_<%= singular_table_name %>
|
||||
@<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
|
||||
end
|
||||
|
||||
# Never trust parameters from the scary internet, only allow the white list through.
|
||||
def <%= "#{singular_table_name}_params" %>
|
||||
<%- if attributes_names.empty? -%>
|
||||
params[<%= ":#{singular_table_name}" %>]
|
||||
<%- else -%>
|
||||
params.require(<%= ":#{singular_table_name}" %>).permit(<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>)
|
||||
<%- end -%>
|
||||
end
|
||||
end
|
||||
<% end -%>
|
||||
@ -1,8 +0,0 @@
|
||||
<% module_namespacing do -%>
|
||||
class <%= class_name %>Serializer < <%= parent_class_name %>
|
||||
attributes <%= attributes_names.map(&:inspect).join(", ") %>
|
||||
<% association_names.each do |attribute| -%>
|
||||
has_one :<%= attribute %>
|
||||
<% end -%>
|
||||
end
|
||||
<% end -%>
|
||||
@ -1,22 +0,0 @@
|
||||
module ActiveModel
|
||||
class Railtie < Rails::Railtie
|
||||
initializer 'generators' do |app|
|
||||
app.load_generators
|
||||
require 'active_model/serializer/generators/serializer/serializer_generator'
|
||||
require 'active_model/serializer/generators/serializer/scaffold_controller_generator'
|
||||
require 'active_model/serializer/generators/resource_override'
|
||||
end
|
||||
|
||||
initializer 'include_routes.active_model_serializer' do |app|
|
||||
ActiveSupport.on_load(:active_model_serializers) do
|
||||
include app.routes.url_helpers
|
||||
end
|
||||
end
|
||||
|
||||
config.to_prepare do
|
||||
ActiveModel::Serializer.serializers_cache.clear
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActiveSupport.run_load_hooks(:active_model_serializers, ActiveModel::Serializer)
|
||||
@ -1,5 +0,0 @@
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
VERSION = '0.9.8'.freeze
|
||||
end
|
||||
end
|
||||
@ -1,5 +0,0 @@
|
||||
module ActiveModel
|
||||
module SerializerSupport
|
||||
alias read_attribute_for_serialization send
|
||||
end
|
||||
end
|
||||
@ -1,20 +0,0 @@
|
||||
require 'active_model'
|
||||
require 'active_model/serializer'
|
||||
require 'active_model/serializer_support'
|
||||
require 'active_model/serializer/version'
|
||||
require 'active_model/serializer/railtie' if defined?(Rails)
|
||||
|
||||
begin
|
||||
require 'action_controller'
|
||||
require 'action_controller/serialization'
|
||||
require 'action_controller/serialization_test_case'
|
||||
|
||||
ActiveSupport.on_load(:action_controller) do
|
||||
if ::ActionController::Serialization.enabled
|
||||
ActionController::Base.send(:include, ::ActionController::Serialization)
|
||||
ActionController::TestCase.send(:include, ::ActionController::SerializationAssertions)
|
||||
end
|
||||
end
|
||||
rescue LoadError
|
||||
# rails not installed, continuing
|
||||
end
|
||||
@ -1,60 +0,0 @@
|
||||
# https://github.com/rails-api/active_model_serializers/pull/872
|
||||
# approx ref 792fb8a9053f8db3c562dae4f40907a582dd1720 to test against
|
||||
require 'bundler/setup'
|
||||
|
||||
require 'rails'
|
||||
require 'active_model'
|
||||
require 'active_support'
|
||||
require 'active_support/json'
|
||||
require 'action_controller'
|
||||
require 'action_controller/test_case'
|
||||
require 'action_controller/railtie'
|
||||
abort "Rails application already defined: #{Rails.application.class}" if Rails.application
|
||||
|
||||
class NullLogger < Logger
|
||||
def initialize(*_args)
|
||||
end
|
||||
|
||||
def add(*_args, &_block)
|
||||
end
|
||||
end
|
||||
class BenchmarkLogger < ActiveSupport::Logger
|
||||
def initialize
|
||||
@file = StringIO.new
|
||||
super(@file)
|
||||
end
|
||||
|
||||
def messages
|
||||
@file.rewind
|
||||
@file.read
|
||||
end
|
||||
end
|
||||
# ref: https://gist.github.com/bf4/8744473
|
||||
class BenchmarkApp < Rails::Application
|
||||
# Set up production configuration
|
||||
config.eager_load = true
|
||||
config.cache_classes = true
|
||||
# CONFIG: CACHE_ON={on,off}
|
||||
config.action_controller.perform_caching = ENV['CACHE_ON'] != 'off'
|
||||
config.action_controller.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
|
||||
|
||||
config.active_support.test_order = :random
|
||||
config.secret_token = 'S' * 30
|
||||
config.secret_key_base = 'abc123'
|
||||
config.consider_all_requests_local = false
|
||||
|
||||
# otherwise deadlock occurred
|
||||
config.middleware.delete 'Rack::Lock'
|
||||
|
||||
# to disable log files
|
||||
config.logger = NullLogger.new
|
||||
config.active_support.deprecation = :log
|
||||
config.log_level = :info
|
||||
end
|
||||
|
||||
require 'active_model_serializers'
|
||||
|
||||
# Initialize app before any serializers are defined, for running across revisions.
|
||||
# ref: https://github.com/rails-api/active_model_serializers/pull/1478
|
||||
Rails.application.initialize!
|
||||
|
||||
@ -1,67 +0,0 @@
|
||||
require 'benchmark/ips'
|
||||
require 'json'
|
||||
|
||||
# Add benchmarking runner from ruby-bench-suite
|
||||
# https://github.com/ruby-bench/ruby-bench-suite/blob/master/rails/benchmarks/support/benchmark_rails.rb
|
||||
module Benchmark
|
||||
module ActiveModelSerializers
|
||||
module TestMethods
|
||||
def request(method, path)
|
||||
response = Rack::MockRequest.new(BenchmarkApp).send(method, path)
|
||||
if response.status.in?([404, 500])
|
||||
fail "omg, #{method}, #{path}, '#{response.status}', '#{response.body}'"
|
||||
end
|
||||
response
|
||||
end
|
||||
end
|
||||
|
||||
# extend Benchmark with an `ams` method
|
||||
def ams(label = nil, time:, disable_gc: true, warmup: 3, &block)
|
||||
fail ArgumentError.new, 'block should be passed' unless block_given?
|
||||
|
||||
if disable_gc
|
||||
GC.disable
|
||||
else
|
||||
GC.enable
|
||||
end
|
||||
|
||||
report = Benchmark.ips(time, warmup, true) do |x|
|
||||
x.report(label) { yield }
|
||||
end
|
||||
|
||||
entry = report.entries.first
|
||||
|
||||
output = {
|
||||
label: label,
|
||||
version: ::ActiveModel::Serializer::VERSION.to_s,
|
||||
rails_version: ::Rails.version.to_s,
|
||||
iterations_per_second: entry.ips,
|
||||
iterations_per_second_standard_deviation: entry.error_percentage,
|
||||
total_allocated_objects_per_iteration: count_total_allocated_objects(&block)
|
||||
}.to_json
|
||||
|
||||
puts output
|
||||
output
|
||||
end
|
||||
|
||||
def count_total_allocated_objects
|
||||
if block_given?
|
||||
key =
|
||||
if RUBY_VERSION < '2.2'
|
||||
:total_allocated_object
|
||||
else
|
||||
:total_allocated_objects
|
||||
end
|
||||
|
||||
before = GC.stat[key]
|
||||
yield
|
||||
after = GC.stat[key]
|
||||
after - before
|
||||
else
|
||||
-1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
extend Benchmark::ActiveModelSerializers
|
||||
end
|
||||
@ -1,41 +0,0 @@
|
||||
require_relative './benchmarking_support'
|
||||
require_relative './app'
|
||||
require_relative './setup'
|
||||
|
||||
time = 10
|
||||
disable_gc = true
|
||||
|
||||
|
||||
|
||||
authors_query = Author.preload(:posts).preload(:profile)
|
||||
author = authors_query.first
|
||||
authors = authors_query.to_a
|
||||
|
||||
|
||||
Benchmark.ams('Single: DefaultSerializer', time: time, disable_gc: disable_gc) do
|
||||
ActiveModel::DefaultSerializer.new(author).to_json
|
||||
end
|
||||
|
||||
Benchmark.ams('ArraySerializer', time: time, disable_gc: disable_gc) do
|
||||
ActiveModel::ArraySerializer.new(authors).to_json
|
||||
end
|
||||
|
||||
Benchmark.ams('ArraySerializer: each_serializer: DefaultSerializer', time: time, disable_gc: disable_gc) do
|
||||
ActiveModel::ArraySerializer.new(authors, each_serializer:ActiveModel::DefaultSerializer).to_json
|
||||
end
|
||||
|
||||
Benchmark.ams('FlatAuthorSerializer', time: time, disable_gc: disable_gc) do
|
||||
FlatAuthorSerializer.new(author).to_json
|
||||
end
|
||||
|
||||
Benchmark.ams('ArraySerializer: each_serializer: FlatAuthorSerializer', time: time, disable_gc: disable_gc) do
|
||||
ActiveModel::ArraySerializer.new(authors, each_serializer: FlatAuthorSerializer).to_json
|
||||
end
|
||||
|
||||
Benchmark.ams('AuthorWithDefaultRelationshipsSerializer', time: time, disable_gc: disable_gc) do
|
||||
AuthorWithDefaultRelationshipsSerializer.new(author).to_json
|
||||
end
|
||||
|
||||
Benchmark.ams('ArraySerializer: each_serializer: AuthorWithDefaultRelationshipsSerializer', time: time, disable_gc: disable_gc) do
|
||||
ActiveModel::ArraySerializer.new(authors, each_serializer: AuthorWithDefaultRelationshipsSerializer).to_json
|
||||
end
|
||||
@ -1,75 +0,0 @@
|
||||
###########################################
|
||||
# Setup active record models
|
||||
##########################################
|
||||
require 'active_record'
|
||||
require 'sqlite3'
|
||||
|
||||
|
||||
# Change the following to reflect your database settings
|
||||
ActiveRecord::Base.establish_connection(
|
||||
adapter: 'sqlite3',
|
||||
database: ':memory:'
|
||||
)
|
||||
|
||||
# Don't show migration output when constructing fake db
|
||||
ActiveRecord::Migration.verbose = false
|
||||
|
||||
ActiveRecord::Schema.define do
|
||||
create_table :authors, force: true do |t|
|
||||
t.string :name
|
||||
end
|
||||
|
||||
create_table :posts, force: true do |t|
|
||||
t.text :body
|
||||
t.string :title
|
||||
t.references :author
|
||||
end
|
||||
|
||||
create_table :profiles, force: true do |t|
|
||||
t.text :project_url
|
||||
t.text :bio
|
||||
t.date :birthday
|
||||
t.references :author
|
||||
end
|
||||
end
|
||||
|
||||
class Author < ActiveRecord::Base
|
||||
has_one :profile
|
||||
has_many :posts
|
||||
end
|
||||
|
||||
class Post < ActiveRecord::Base
|
||||
belongs_to :author
|
||||
end
|
||||
|
||||
class Profile < ActiveRecord::Base
|
||||
belongs_to :author
|
||||
end
|
||||
|
||||
# Build out the data to serialize
|
||||
author = Author.create(name: 'Preston Sego')
|
||||
Profile.create(project_url: 'https://github.com/NullVoxPopuli', author: author)
|
||||
50.times do
|
||||
Post.create(
|
||||
body: 'something about how password restrictions are evil, and less secure, and with the math to prove it.',
|
||||
title: 'Your bank is does not know how to do security',
|
||||
author: author
|
||||
)
|
||||
end
|
||||
|
||||
ActiveModel::Serializer.root = false
|
||||
ActiveModel::ArraySerializer.root = false
|
||||
|
||||
class FlatAuthorSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name
|
||||
end
|
||||
|
||||
class AuthorWithDefaultRelationshipsSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name
|
||||
|
||||
has_one :profile
|
||||
has_many :posts
|
||||
end
|
||||
|
||||
# For debugging SQL output
|
||||
#ActiveRecord::Base.logger = Logger.new(STDERR)
|
||||
96
test/fixtures/active_record.rb
vendored
96
test/fixtures/active_record.rb
vendored
@ -1,96 +0,0 @@
|
||||
require 'active_record'
|
||||
|
||||
ActiveRecord::Base.establish_connection(
|
||||
:adapter => 'sqlite3',
|
||||
:database => ':memory:'
|
||||
)
|
||||
|
||||
ActiveRecord::Schema.define do
|
||||
create_table :ar_posts, force: true do |t|
|
||||
t.string :title
|
||||
t.text :body
|
||||
t.belongs_to :ar_section, index: true
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :ar_comments, force: true do |t|
|
||||
t.text :body
|
||||
t.belongs_to :ar_post, index: true
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :ar_tags, force: true do |t|
|
||||
t.string :name
|
||||
end
|
||||
|
||||
create_table :ar_sections, force: true do |t|
|
||||
t.string :name
|
||||
end
|
||||
|
||||
create_table :ar_posts_tags, force: true do |t|
|
||||
t.references :ar_post, :ar_tag, index: true
|
||||
end
|
||||
|
||||
create_table :ar_comments_tags, force: true do |t|
|
||||
t.references :ar_comment, :ar_tag, index: true
|
||||
end
|
||||
end
|
||||
|
||||
class ARPost < ActiveRecord::Base
|
||||
has_many :ar_comments, class_name: 'ARComment'
|
||||
has_and_belongs_to_many :ar_tags, class_name: 'ARTag', join_table: :ar_posts_tags
|
||||
belongs_to :ar_section, class_name: 'ARSection'
|
||||
end
|
||||
|
||||
class ARComment < ActiveRecord::Base
|
||||
belongs_to :ar_post, class_name: 'ARPost'
|
||||
has_and_belongs_to_many :ar_tags, class_name: 'ARTag', join_table: :ar_comments_tags
|
||||
end
|
||||
|
||||
class ARTag < ActiveRecord::Base
|
||||
end
|
||||
|
||||
class ARSection < ActiveRecord::Base
|
||||
end
|
||||
|
||||
class ARPostSerializer < ActiveModel::Serializer
|
||||
attributes :title, :body
|
||||
|
||||
has_many :ar_comments, :ar_tags
|
||||
has_one :ar_section
|
||||
end
|
||||
|
||||
class ARCommentSerializer < ActiveModel::Serializer
|
||||
attributes :body
|
||||
|
||||
has_many :ar_tags
|
||||
end
|
||||
|
||||
class ARTagSerializer < ActiveModel::Serializer
|
||||
attributes :name
|
||||
end
|
||||
|
||||
class ARSectionSerializer < ActiveModel::Serializer
|
||||
attributes 'name'
|
||||
end
|
||||
|
||||
class AREmbeddedSerializer < ActiveModel::Serializer
|
||||
has_many :ar_tags, :ar_comments
|
||||
end
|
||||
|
||||
ARPost.create(title: 'New post',
|
||||
body: 'A body!!!',
|
||||
ar_section: ARSection.create(name: 'ruby')).tap do |post|
|
||||
|
||||
short_tag = post.ar_tags.create(name: 'short')
|
||||
whiny_tag = post.ar_tags.create(name: 'whiny')
|
||||
happy_tag = ARTag.create(name: 'happy')
|
||||
|
||||
post.ar_comments.create(body: 'what a dumb post').tap do |comment|
|
||||
comment.ar_tags.concat happy_tag, whiny_tag
|
||||
end
|
||||
|
||||
post.ar_comments.create(body: 'i liked it').tap do |comment|
|
||||
comment.ar_tags.concat happy_tag, short_tag
|
||||
end
|
||||
end
|
||||
223
test/fixtures/poro.rb
vendored
223
test/fixtures/poro.rb
vendored
@ -1,223 +0,0 @@
|
||||
class Model
|
||||
def initialize(hash = {})
|
||||
@attributes = hash
|
||||
end
|
||||
|
||||
def read_attribute_for_serialization(name)
|
||||
if name == :id || name == 'id'
|
||||
object_id
|
||||
elsif respond_to?(name)
|
||||
send name
|
||||
else
|
||||
@attributes[name]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
###
|
||||
## Models
|
||||
###
|
||||
class User < Model
|
||||
def profile
|
||||
@profile ||= Profile.new(name: 'N1', description: 'D1')
|
||||
end
|
||||
end
|
||||
|
||||
class UserInfo < Model
|
||||
def user
|
||||
@user ||= User.new(name: 'N1', email: 'E1')
|
||||
end
|
||||
end
|
||||
|
||||
class Profile < Model
|
||||
end
|
||||
|
||||
class Category < Model
|
||||
def posts
|
||||
@posts ||= [Post.new(title: 'T1', body: 'B1'),
|
||||
Post.new(title: 'T2', body: 'B2')]
|
||||
end
|
||||
end
|
||||
|
||||
class Post < Model
|
||||
def comments
|
||||
@comments ||= [Comment.new(content: 'C1'),
|
||||
Comment.new(content: 'C2')]
|
||||
end
|
||||
end
|
||||
|
||||
class SpecialPost < Post
|
||||
def special_comment
|
||||
@special_comment ||= Comment.new(content: 'special')
|
||||
end
|
||||
end
|
||||
|
||||
class Type < Model
|
||||
end
|
||||
|
||||
class SelfReferencingUser < Model
|
||||
def type
|
||||
@type ||= Type.new(name: 'N1')
|
||||
end
|
||||
def parent
|
||||
@parent ||= SelfReferencingUserParent.new(name: 'N1')
|
||||
end
|
||||
end
|
||||
|
||||
class SelfReferencingUserParent < Model
|
||||
def type
|
||||
@type ||= Type.new(name: 'N2')
|
||||
end
|
||||
def parent
|
||||
end
|
||||
end
|
||||
|
||||
class Comment < Model
|
||||
end
|
||||
|
||||
class WebLog < Model
|
||||
end
|
||||
|
||||
class Interview < Model
|
||||
def attachment
|
||||
@attachment ||= Image.new(url: 'U1')
|
||||
end
|
||||
end
|
||||
|
||||
class Mail < Model
|
||||
def attachments
|
||||
@attachments ||= [Image.new(url: 'U1'),
|
||||
Video.new(html: 'H1')]
|
||||
end
|
||||
end
|
||||
|
||||
class Image < Model
|
||||
end
|
||||
|
||||
class Video < Model
|
||||
end
|
||||
|
||||
###
|
||||
## Serializers
|
||||
###
|
||||
class UserSerializer < ActiveModel::Serializer
|
||||
attributes :name, :email
|
||||
|
||||
has_one :profile
|
||||
end
|
||||
|
||||
class TypeSerializer < ActiveModel::Serializer
|
||||
attributes :name
|
||||
end
|
||||
|
||||
class SelfReferencingUserParentSerializer < ActiveModel::Serializer
|
||||
attributes :name
|
||||
has_one :type, serializer: TypeSerializer, embed: :ids, include: true
|
||||
end
|
||||
|
||||
class SelfReferencingUserSerializer < ActiveModel::Serializer
|
||||
attributes :name
|
||||
|
||||
has_one :type, serializer: TypeSerializer, embed: :ids, include: true
|
||||
has_one :parent, serializer: SelfReferencingUserSerializer, embed: :ids, include: true
|
||||
end
|
||||
|
||||
class UserInfoSerializer < ActiveModel::Serializer
|
||||
has_one :user, serializer: UserSerializer
|
||||
end
|
||||
|
||||
class ProfileSerializer < ActiveModel::Serializer
|
||||
def description
|
||||
description = object.read_attribute_for_serialization(:description)
|
||||
scope ? "#{description} - #{scope}" : description
|
||||
end
|
||||
|
||||
attributes :name, :description
|
||||
end
|
||||
|
||||
class CategorySerializer < ActiveModel::Serializer
|
||||
attributes :name
|
||||
|
||||
has_many :posts
|
||||
end
|
||||
|
||||
class PostSerializer < ActiveModel::Serializer
|
||||
attributes :title, :body
|
||||
|
||||
def title
|
||||
keyword = serialization_options[:highlight_keyword]
|
||||
title = object.read_attribute_for_serialization(:title)
|
||||
title = title.gsub(keyword,"'#{keyword}'") if keyword
|
||||
title
|
||||
end
|
||||
|
||||
has_many :comments
|
||||
end
|
||||
|
||||
class SpecialPostSerializer < ActiveModel::Serializer
|
||||
attributes :title, :body
|
||||
has_many :comments, root: :comments, embed_in_root: true, embed: :ids
|
||||
has_one :special_comment, root: :comments, embed_in_root: true, embed: :ids
|
||||
end
|
||||
|
||||
class CommentSerializer < ActiveModel::Serializer
|
||||
attributes :content
|
||||
end
|
||||
|
||||
class WebLogSerializer < ActiveModel::Serializer
|
||||
attributes :name, :display_name
|
||||
end
|
||||
|
||||
class WebLogLowerCamelSerializer < WebLogSerializer
|
||||
format_keys :lower_camel
|
||||
end
|
||||
|
||||
class InterviewSerializer < ActiveModel::Serializer
|
||||
attributes :text
|
||||
|
||||
has_one :attachment, polymorphic: true
|
||||
end
|
||||
|
||||
class MailSerializer < ActiveModel::Serializer
|
||||
attributes :body
|
||||
|
||||
has_many :attachments, polymorphic: true
|
||||
end
|
||||
|
||||
class ImageSerializer < ActiveModel::Serializer
|
||||
attributes :url
|
||||
end
|
||||
|
||||
class VideoSerializer < ActiveModel::Serializer
|
||||
attributes :html
|
||||
end
|
||||
|
||||
class ShortProfileSerializer < ::ProfileSerializer; end
|
||||
|
||||
module TestNamespace
|
||||
class ProfileSerializer < ::ProfileSerializer; end
|
||||
class UserSerializer < ::UserSerializer; end
|
||||
end
|
||||
|
||||
ActiveModel::Serializer.setup do |config|
|
||||
config.default_key_type = :name
|
||||
end
|
||||
|
||||
class NameKeyUserSerializer < ActiveModel::Serializer
|
||||
attributes :name, :email
|
||||
|
||||
has_one :profile
|
||||
end
|
||||
|
||||
class NameKeyPostSerializer < ActiveModel::Serializer
|
||||
attributes :title, :body
|
||||
|
||||
has_many :comments
|
||||
end
|
||||
|
||||
ActiveModel::Serializer.setup do |config|
|
||||
config.default_key_type = nil
|
||||
end
|
||||
|
||||
|
||||
1
test/fixtures/template.html.erb
vendored
1
test/fixtures/template.html.erb
vendored
@ -1 +0,0 @@
|
||||
<p>Hello.</p>
|
||||
@ -1,105 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActionController
|
||||
module Serialization
|
||||
class NamespacedSerializationTest < ActionController::TestCase
|
||||
class TestNamespace::MyController < ActionController::Base
|
||||
def render_profile_with_namespace
|
||||
render json: Profile.new({ name: 'Name 1', description: 'Description 1'})
|
||||
end
|
||||
|
||||
def render_profiles_with_namespace
|
||||
render json: [Profile.new({ name: 'Name 1', description: 'Description 1'})]
|
||||
end
|
||||
|
||||
def render_comment
|
||||
render json: Comment.new(content: 'Comment 1')
|
||||
end
|
||||
|
||||
def render_comments
|
||||
render json: [Comment.new(content: 'Comment 1')]
|
||||
end
|
||||
|
||||
def render_hash
|
||||
render json: {message: 'not found'}, status: 404
|
||||
end
|
||||
end
|
||||
|
||||
tests TestNamespace::MyController
|
||||
|
||||
def test_render_profile_with_namespace
|
||||
get :render_profile_with_namespace
|
||||
assert_serializer TestNamespace::ProfileSerializer
|
||||
end
|
||||
|
||||
def test_render_profiles_with_namespace
|
||||
get :render_profiles_with_namespace
|
||||
assert_serializer TestNamespace::ProfileSerializer
|
||||
end
|
||||
|
||||
def test_fallback_to_a_version_without_namespace
|
||||
get :render_comment
|
||||
assert_serializer CommentSerializer
|
||||
end
|
||||
|
||||
def test_array_fallback_to_a_version_without_namespace
|
||||
get :render_comments
|
||||
assert_serializer CommentSerializer
|
||||
end
|
||||
|
||||
def test_render_hash_regression
|
||||
get :render_hash
|
||||
assert_equal JSON.parse(response.body), {'message' => 'not found'}
|
||||
end
|
||||
end
|
||||
|
||||
class OptionNamespacedSerializationTest < ActionController::TestCase
|
||||
class MyController < ActionController::Base
|
||||
def default_serializer_options
|
||||
{
|
||||
namespace: TestNamespace
|
||||
}
|
||||
end
|
||||
|
||||
def render_profile_with_namespace_option
|
||||
render json: Profile.new({ name: 'Name 1', description: 'Description 1'})
|
||||
end
|
||||
|
||||
def render_profiles_with_namespace_option
|
||||
render json: [Profile.new({ name: 'Name 1', description: 'Description 1'})]
|
||||
end
|
||||
|
||||
def render_comment
|
||||
render json: Comment.new(content: 'Comment 1')
|
||||
end
|
||||
|
||||
def render_comments
|
||||
render json: [Comment.new(content: 'Comment 1')]
|
||||
end
|
||||
end
|
||||
|
||||
tests MyController
|
||||
|
||||
def test_render_profile_with_namespace_option
|
||||
get :render_profile_with_namespace_option
|
||||
assert_serializer TestNamespace::ProfileSerializer
|
||||
end
|
||||
|
||||
def test_render_profiles_with_namespace_option
|
||||
get :render_profiles_with_namespace_option
|
||||
assert_serializer TestNamespace::ProfileSerializer
|
||||
end
|
||||
|
||||
def test_fallback_to_a_version_without_namespace
|
||||
get :render_comment
|
||||
assert_serializer CommentSerializer
|
||||
end
|
||||
|
||||
def test_array_fallback_to_a_version_without_namespace
|
||||
get :render_comments
|
||||
assert_serializer CommentSerializer
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@ -1,287 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActionController
|
||||
module Serialization
|
||||
class ImplicitSerializerTest < ActionController::TestCase
|
||||
class MyController < ActionController::Base
|
||||
def render_using_implicit_serializer
|
||||
render json: Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
end
|
||||
end
|
||||
|
||||
tests MyController
|
||||
|
||||
def test_render_using_implicit_serializer
|
||||
get :render_using_implicit_serializer
|
||||
assert_equal 'application/json', @response.content_type
|
||||
assert_equal '{"profile":{"name":"Name 1","description":"Description 1"}}', @response.body
|
||||
end
|
||||
end
|
||||
|
||||
class ImplicitSerializerScopeTest < ActionController::TestCase
|
||||
class MyController < ActionController::Base
|
||||
def render_using_implicit_serializer_and_scope
|
||||
render json: Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_user
|
||||
'current_user'
|
||||
end
|
||||
end
|
||||
|
||||
tests MyController
|
||||
|
||||
def test_render_using_implicit_serializer_and_scope
|
||||
get :render_using_implicit_serializer_and_scope
|
||||
assert_equal 'application/json', @response.content_type
|
||||
assert_equal '{"profile":{"name":"Name 1","description":"Description 1 - current_user"}}', @response.body
|
||||
end
|
||||
end
|
||||
|
||||
class DefaultOptionsForSerializerScopeTest < ActionController::TestCase
|
||||
class MyController < ActionController::Base
|
||||
def default_serializer_options
|
||||
{ scope: current_admin }
|
||||
end
|
||||
|
||||
def render_using_scope_set_in_default_serializer_options
|
||||
render json: Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_user
|
||||
'current_user'
|
||||
end
|
||||
|
||||
def current_admin
|
||||
'current_admin'
|
||||
end
|
||||
end
|
||||
|
||||
tests MyController
|
||||
|
||||
def test_render_using_scope_set_in_default_serializer_options
|
||||
get :render_using_scope_set_in_default_serializer_options
|
||||
assert_equal 'application/json', @response.content_type
|
||||
assert_equal '{"profile":{"name":"Name 1","description":"Description 1 - current_admin"}}', @response.body
|
||||
end
|
||||
end
|
||||
|
||||
class ExplicitSerializerScopeTest < ActionController::TestCase
|
||||
class MyController < ActionController::Base
|
||||
def render_using_implicit_serializer_and_explicit_scope
|
||||
render json: Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }), scope: current_admin
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_user
|
||||
'current_user'
|
||||
end
|
||||
|
||||
def current_admin
|
||||
'current_admin'
|
||||
end
|
||||
end
|
||||
|
||||
tests MyController
|
||||
|
||||
def test_render_using_implicit_serializer_and_explicit_scope
|
||||
get :render_using_implicit_serializer_and_explicit_scope
|
||||
assert_equal 'application/json', @response.content_type
|
||||
assert_equal '{"profile":{"name":"Name 1","description":"Description 1 - current_admin"}}', @response.body
|
||||
end
|
||||
end
|
||||
|
||||
class OverridingSerializationScopeTest < ActionController::TestCase
|
||||
class MyController < ActionController::Base
|
||||
def render_overriding_serialization_scope
|
||||
render json: Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_user
|
||||
'current_user'
|
||||
end
|
||||
|
||||
def serialization_scope
|
||||
'current_admin'
|
||||
end
|
||||
end
|
||||
|
||||
tests MyController
|
||||
|
||||
def test_render_overriding_serialization_scope
|
||||
get :render_overriding_serialization_scope
|
||||
assert_equal 'application/json', @response.content_type
|
||||
assert_equal '{"profile":{"name":"Name 1","description":"Description 1 - current_admin"}}', @response.body
|
||||
end
|
||||
end
|
||||
|
||||
class CallingSerializationScopeTest < ActionController::TestCase
|
||||
class MyController < ActionController::Base
|
||||
def render_calling_serialization_scope
|
||||
render json: Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_user
|
||||
'current_user'
|
||||
end
|
||||
|
||||
serialization_scope :current_user
|
||||
end
|
||||
|
||||
tests MyController
|
||||
|
||||
def test_render_calling_serialization_scope
|
||||
get :render_calling_serialization_scope
|
||||
assert_equal 'application/json', @response.content_type
|
||||
assert_equal '{"profile":{"name":"Name 1","description":"Description 1 - current_user"}}', @response.body
|
||||
end
|
||||
end
|
||||
|
||||
class JSONDumpSerializerTest < ActionController::TestCase
|
||||
class MyController < ActionController::Base
|
||||
def render_using_json_dump
|
||||
render json: JSON.dump(hello: 'world')
|
||||
end
|
||||
end
|
||||
|
||||
tests MyController
|
||||
|
||||
def test_render_using_json_dump
|
||||
get :render_using_json_dump
|
||||
assert_equal 'application/json', @response.content_type
|
||||
assert_equal '{"hello":"world"}', @response.body
|
||||
end
|
||||
end
|
||||
|
||||
class RailsSerializerTest < ActionController::TestCase
|
||||
class MyController < ActionController::Base
|
||||
def render_using_rails_behavior
|
||||
render json: [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })], serializer: false
|
||||
end
|
||||
end
|
||||
|
||||
tests MyController
|
||||
|
||||
def test_render_using_rails_behavior
|
||||
get :render_using_rails_behavior
|
||||
assert_equal 'application/json', @response.content_type
|
||||
assert_equal '[{"attributes":{"name":"Name 1","description":"Description 1","comments":"Comments 1"}}]', @response.body
|
||||
end
|
||||
end
|
||||
|
||||
class ArraySerializerTest < ActionController::TestCase
|
||||
class MyController < ActionController::Base
|
||||
def render_array
|
||||
render json: [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })]
|
||||
end
|
||||
end
|
||||
|
||||
tests MyController
|
||||
|
||||
def test_render_array
|
||||
get :render_array
|
||||
assert_equal 'application/json', @response.content_type
|
||||
assert_equal '{"my":[{"name":"Name 1","description":"Description 1"}]}', @response.body
|
||||
end
|
||||
end
|
||||
|
||||
class LowerCamelArraySerializerTest < ActionController::TestCase
|
||||
class WebLogController < ActionController::Base
|
||||
def render_array
|
||||
render json: [WebLog.new({name: 'Name 1', display_name: 'Display Name 1'}), WebLog.new({name: 'Name 2', display_name: 'Display Name 2'})], each_serializer: WebLogLowerCamelSerializer
|
||||
end
|
||||
end
|
||||
|
||||
tests WebLogController
|
||||
|
||||
def test_render_array
|
||||
get :render_array
|
||||
assert_equal 'application/json', @response.content_type
|
||||
assert_equal '{"webLog":[{"name":"Name 1","displayName":"Display Name 1"},{"name":"Name 2","displayName":"Display Name 2"}]}', @response.body
|
||||
end
|
||||
end
|
||||
|
||||
class LowerCamelWoRootSerializerTest < ActionController::TestCase
|
||||
class WebLogController < ActionController::Base
|
||||
def render_without_root
|
||||
render json: WebLog.new({name: 'Name 1', display_name: 'Display Name 1'}),
|
||||
root: false,
|
||||
serializer: WebLogLowerCamelSerializer
|
||||
end
|
||||
end
|
||||
|
||||
tests WebLogController
|
||||
|
||||
def test_render_without_root
|
||||
get :render_without_root
|
||||
assert_equal 'application/json', @response.content_type
|
||||
assert_equal '{"name":"Name 1","displayName":"Display Name 1"}', @response.body
|
||||
end
|
||||
end
|
||||
|
||||
class LowerCamelArrayWoRootSerializerTest < ActionController::TestCase
|
||||
class WebLogController < ActionController::Base
|
||||
def render_array_without_root
|
||||
render json: [WebLog.new({name: 'Name 1', display_name: 'Display Name 1'}),
|
||||
WebLog.new({name: 'Name 2', display_name: 'Display Name 2'})],
|
||||
root: false,
|
||||
each_serializer: WebLogLowerCamelSerializer
|
||||
end
|
||||
end
|
||||
|
||||
tests WebLogController
|
||||
|
||||
def test_render_array_without_root
|
||||
get :render_array_without_root
|
||||
assert_equal 'application/json', @response.content_type
|
||||
assert_equal '[{"name":"Name 1","displayName":"Display Name 1"},{"name":"Name 2","displayName":"Display Name 2"}]', @response.body
|
||||
end
|
||||
end
|
||||
|
||||
class ArrayEmbedingSerializerTest < ActionController::TestCase
|
||||
def setup
|
||||
super
|
||||
@association = UserSerializer._associations[:profile]
|
||||
@old_association = @association.dup
|
||||
end
|
||||
|
||||
def teardown
|
||||
super
|
||||
UserSerializer._associations[:profile] = @old_association
|
||||
end
|
||||
|
||||
class MyController < ActionController::Base
|
||||
def initialize(*)
|
||||
super
|
||||
@user = User.new({ name: 'Name 1', email: 'mail@server.com', gender: 'M' })
|
||||
end
|
||||
attr_reader :user
|
||||
|
||||
def render_array_embeding_in_root
|
||||
render json: [@user]
|
||||
end
|
||||
end
|
||||
|
||||
tests MyController
|
||||
|
||||
def test_render_array_embeding_in_root
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
|
||||
get :render_array_embeding_in_root
|
||||
assert_equal 'application/json', @response.content_type
|
||||
|
||||
assert_equal("{\"my\":[{\"name\":\"Name 1\",\"email\":\"mail@server.com\",\"profile_id\":#{@controller.user.profile.object_id}}],\"profiles\":[{\"name\":\"N1\",\"description\":\"D1\"}]}", @response.body)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,71 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActionController
|
||||
module SerializationsAssertions
|
||||
class RenderSerializerTest < ActionController::TestCase
|
||||
class MyController < ActionController::Base
|
||||
def render_using_serializer
|
||||
render json: Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
end
|
||||
|
||||
def render_text
|
||||
render text: 'ok'
|
||||
end
|
||||
|
||||
def render_template
|
||||
prepend_view_path "./test/fixtures"
|
||||
render template: "template"
|
||||
end
|
||||
end
|
||||
|
||||
tests MyController
|
||||
|
||||
def test_supports_specifying_serializers_with_a_serializer_class
|
||||
get :render_using_serializer
|
||||
assert_serializer ProfileSerializer
|
||||
end
|
||||
|
||||
def test_supports_specifying_serializers_with_a_regexp
|
||||
get :render_using_serializer
|
||||
assert_serializer %r{\AProfile.+\Z}
|
||||
end
|
||||
|
||||
def test_supports_specifying_serializers_with_a_string
|
||||
get :render_using_serializer
|
||||
assert_serializer 'ProfileSerializer'
|
||||
end
|
||||
|
||||
def test_supports_specifying_serializers_with_a_symbol
|
||||
get :render_using_serializer
|
||||
assert_serializer :profile_serializer
|
||||
end
|
||||
|
||||
def test_supports_specifying_serializers_with_a_nil
|
||||
get :render_text
|
||||
assert_serializer nil
|
||||
end
|
||||
|
||||
def test_raises_descriptive_error_message_when_serializer_was_not_rendered
|
||||
get :render_using_serializer
|
||||
e = assert_raise ActiveSupport::TestCase::Assertion do
|
||||
assert_serializer 'PostSerializer'
|
||||
end
|
||||
assert_match 'expecting <"PostSerializer"> but rendering with <["ProfileSerializer"]>', e.message
|
||||
end
|
||||
|
||||
|
||||
def test_raises_argument_error_when_asserting_with_invalid_object
|
||||
get :render_using_serializer
|
||||
e = assert_raise ArgumentError do
|
||||
assert_serializer Hash
|
||||
end
|
||||
assert_match 'assert_serializer only accepts a String, Symbol, Regexp, ActiveModel::Serializer, or nil', e.message
|
||||
end
|
||||
|
||||
def test_does_not_overwrite_notification_subscriptions
|
||||
get :render_template
|
||||
assert_template "template"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,94 +0,0 @@
|
||||
require 'test_helper'
|
||||
require 'fixtures/active_record'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class ActiveRecordTest < Minitest::Test
|
||||
def setup
|
||||
@post = ARPost.first
|
||||
end
|
||||
|
||||
def test_serialization_embedding_objects
|
||||
post_serializer = ARPostSerializer.new(@post)
|
||||
|
||||
assert_equal({
|
||||
'ar_post' => {
|
||||
title: 'New post', body: 'A body!!!',
|
||||
ar_comments: [{ body: 'what a dumb post', ar_tags: [{ name: 'happy' }, { name: 'whiny' }] },
|
||||
{ body: 'i liked it', ar_tags: [{:name=>"happy"}, {:name=>"short"}] }],
|
||||
ar_tags: [{ name: 'short' }, { name: 'whiny' }],
|
||||
ar_section: { 'name' => 'ruby' }
|
||||
}
|
||||
}, post_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_serialization_embedding_ids
|
||||
post_serializer = ARPostSerializer.new(@post)
|
||||
|
||||
embed(ARPostSerializer, embed: :ids) do
|
||||
assert_equal({
|
||||
'ar_post' => {
|
||||
title: 'New post', body: 'A body!!!',
|
||||
'ar_comment_ids' => [1, 2],
|
||||
'ar_tag_ids' => [1, 2],
|
||||
'ar_section_id' => 1
|
||||
}
|
||||
}, post_serializer.as_json)
|
||||
end
|
||||
end
|
||||
|
||||
def test_serialization_embedding_ids_including_in_root
|
||||
post_serializer = ARPostSerializer.new(@post)
|
||||
|
||||
embed(ARPostSerializer, embed: :ids, embed_in_root: true) do
|
||||
embed(ARCommentSerializer, embed: :ids, embed_in_root: true) do
|
||||
assert_equal({
|
||||
'ar_post' => {
|
||||
title: 'New post', body: 'A body!!!',
|
||||
'ar_comment_ids' => [1, 2],
|
||||
'ar_tag_ids' => [1, 2],
|
||||
'ar_section_id' => 1
|
||||
},
|
||||
'ar_comments' => [{ body: 'what a dumb post', 'ar_tag_ids' => [3, 2] },
|
||||
{ body: 'i liked it', 'ar_tag_ids' => [3, 1] }],
|
||||
'ar_tags' => [{ name: 'happy' }, { name: 'whiny' }, { name: 'short' }],
|
||||
'ar_sections' => [{ 'name' => 'ruby' }]
|
||||
}, post_serializer.as_json)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_serialization_embedding_ids_in_common_root_key
|
||||
post_serializer = AREmbeddedSerializer.new(@post)
|
||||
|
||||
embed(AREmbeddedSerializer, embed: :ids, embed_in_root: true, embed_in_root_key: :linked) do
|
||||
embed(ARCommentSerializer, embed: :ids, embed_in_root: true, embed_in_root_key: :linked) do
|
||||
assert_equal({
|
||||
'ar_tags' => [{ name: 'short' },
|
||||
{ name: 'whiny' },
|
||||
{ name: 'happy' }],
|
||||
'ar_comments' => [{ body: 'what a dumb post', 'ar_tag_ids' => [3, 2] },
|
||||
{ body: 'i liked it', 'ar_tag_ids' => [3, 1] }]
|
||||
}, post_serializer.as_json[:linked])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def embed(serializer_class, options = {})
|
||||
old_assocs = Hash[serializer_class._associations.to_a.map { |(name, association)| [name, association.dup] }]
|
||||
|
||||
serializer_class._associations.each_value do |association|
|
||||
association.embed = options[:embed]
|
||||
association.embed_in_root = options[:embed_in_root]
|
||||
association.embed_in_root_key = options[:embed_in_root_key]
|
||||
end
|
||||
|
||||
yield
|
||||
ensure
|
||||
serializer_class._associations = old_assocs
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,26 +0,0 @@
|
||||
require 'test_helper'
|
||||
require 'rails'
|
||||
require 'active_model/serializer/railtie'
|
||||
require 'test_app'
|
||||
|
||||
class ResourceGeneratorTest < Rails::Generators::TestCase
|
||||
destination File.expand_path('../../../tmp', __FILE__)
|
||||
setup :prepare_destination, :copy_routes
|
||||
|
||||
tests Rails::Generators::ResourceGenerator
|
||||
arguments %w(account)
|
||||
|
||||
def test_serializer_file_is_generated
|
||||
run_generator
|
||||
|
||||
assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < ActiveModel::Serializer/
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def copy_routes
|
||||
config_dir = File.join(destination_root, 'config')
|
||||
FileUtils.mkdir_p(config_dir)
|
||||
File.write(File.join(config_dir, 'routes.rb'), 'Rails.application.routes.draw { }')
|
||||
end
|
||||
end
|
||||
@ -1,64 +0,0 @@
|
||||
require 'test_helper'
|
||||
require 'rails'
|
||||
require 'active_model/serializer/railtie'
|
||||
require 'test_app'
|
||||
|
||||
class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
|
||||
destination File.expand_path('../../../tmp', __FILE__)
|
||||
setup :prepare_destination
|
||||
|
||||
tests Rails::Generators::ScaffoldControllerGenerator
|
||||
arguments %w(account name:string description:text business:references)
|
||||
|
||||
def test_generated_controller
|
||||
return true if Rails::VERSION::MAJOR < 4
|
||||
|
||||
run_generator
|
||||
|
||||
assert_file 'app/controllers/accounts_controller.rb' do |content|
|
||||
assert_instance_method :index, content do |m|
|
||||
assert_match /@accounts = Account\.all/, m
|
||||
assert_match /format.html/, m
|
||||
assert_match /format.json \{ render json: @accounts \}/, m
|
||||
end
|
||||
|
||||
assert_instance_method :show, content do |m|
|
||||
assert_match /format.html/, m
|
||||
assert_match /format.json \{ render json: @account \}/, m
|
||||
end
|
||||
|
||||
assert_instance_method :new, content do |m|
|
||||
assert_match /@account = Account\.new/, m
|
||||
end
|
||||
|
||||
assert_instance_method :edit, content do |m|
|
||||
assert m.blank?
|
||||
end
|
||||
|
||||
assert_instance_method :create, content do |m|
|
||||
assert_match /@account = Account\.new\(account_params\)/, m
|
||||
assert_match /@account\.save/, m
|
||||
assert_match /format\.html \{ redirect_to @account, notice: 'Account was successfully created\.' \}/, m
|
||||
assert_match /format\.json \{ render json: @account, status: :created \}/, m
|
||||
assert_match /format\.html \{ render action: 'new' \}/, m
|
||||
assert_match /format\.json \{ render json: @account\.errors, status: :unprocessable_entity \}/, m
|
||||
end
|
||||
|
||||
assert_instance_method :update, content do |m|
|
||||
assert_match /format\.html \{ redirect_to @account, notice: 'Account was successfully updated\.' \}/, m
|
||||
assert_match /format\.json \{ head :no_content \}/, m
|
||||
assert_match /format\.html \{ render action: 'edit' \}/, m
|
||||
assert_match /format\.json \{ render json: @account.errors, status: :unprocessable_entity \}/, m
|
||||
end
|
||||
|
||||
assert_instance_method :destroy, content do |m|
|
||||
assert_match /@account\.destroy/, m
|
||||
assert_match /format\.html { redirect_to accounts_url \}/, m
|
||||
assert_match /format\.json \{ head :no_content \}/, m
|
||||
end
|
||||
|
||||
assert_match(/def account_params/, content)
|
||||
assert_match(/params\.require\(:account\)\.permit\(:name, :description, :business_id\)/, content)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,41 +0,0 @@
|
||||
require 'test_helper'
|
||||
require 'rails'
|
||||
require 'active_model/serializer/railtie'
|
||||
require 'test_app'
|
||||
|
||||
class SerializerGeneratorTest < Rails::Generators::TestCase
|
||||
destination File.expand_path('../../../tmp', __FILE__)
|
||||
setup :prepare_destination
|
||||
|
||||
tests Rails::Generators::SerializerGenerator
|
||||
arguments %w(account name:string description:text business:references)
|
||||
|
||||
def test_generates_a_serializer_with_attributes_and_associations
|
||||
run_generator
|
||||
assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < ActiveModel::Serializer/ do |serializer|
|
||||
assert_match(/attributes :id, :name, :description/, serializer)
|
||||
assert_match(/has_one :business/, serializer)
|
||||
end
|
||||
end
|
||||
|
||||
def test_generates_a_namespaced_serializer
|
||||
run_generator ['admin/account']
|
||||
assert_file 'app/serializers/admin/account_serializer.rb', /class Admin::AccountSerializer < ActiveModel::Serializer/
|
||||
end
|
||||
|
||||
def test_uses_application_serializer_if_one_exists
|
||||
Object.const_set(:ApplicationSerializer, Class.new)
|
||||
run_generator
|
||||
assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < ApplicationSerializer/
|
||||
ensure
|
||||
Object.send :remove_const, :ApplicationSerializer
|
||||
end
|
||||
|
||||
def test_uses_given_parent
|
||||
Object.const_set(:ApplicationSerializer, Class.new)
|
||||
run_generator ['Account', '--parent=MySerializer']
|
||||
assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < MySerializer/
|
||||
ensure
|
||||
Object.send :remove_const, :ApplicationSerializer
|
||||
end
|
||||
end
|
||||
@ -1,14 +0,0 @@
|
||||
class TestApp < Rails::Application
|
||||
if Rails.version.to_s.first >= '4'
|
||||
config.eager_load = false
|
||||
config.secret_key_base = 'abc123'
|
||||
end
|
||||
config.after_initialize do
|
||||
Rails.application.routes.default_url_options = { host: 'http://example.com' }
|
||||
end
|
||||
|
||||
# Set up a logger to avoid creating a log directory on every run.
|
||||
config.logger = Logger.new(nil)
|
||||
end
|
||||
|
||||
TestApp.initialize!
|
||||
@ -1,24 +0,0 @@
|
||||
require 'bundler/setup'
|
||||
require 'minitest/autorun'
|
||||
require 'active_model_serializers'
|
||||
require 'fixtures/poro'
|
||||
|
||||
# Ensure backward compatibility with Minitest 4
|
||||
Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test)
|
||||
|
||||
module TestHelper
|
||||
Routes = ActionDispatch::Routing::RouteSet.new
|
||||
Routes.draw do
|
||||
get ':controller(/:action(/:id))'
|
||||
get ':controller(/:action)'
|
||||
end
|
||||
|
||||
ActionController::Base.send :include, Routes.url_helpers
|
||||
ActionController::Base.send :include, ActionController::Serialization
|
||||
end
|
||||
|
||||
ActionController::TestCase.class_eval do
|
||||
def setup
|
||||
@routes = TestHelper::Routes
|
||||
end
|
||||
end
|
||||
@ -1,18 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class ArraySerializer
|
||||
class ExceptTest < Minitest::Test
|
||||
def test_array_serializer_pass_except_to_items_serializers
|
||||
array = [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }),
|
||||
Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })]
|
||||
serializer = ArraySerializer.new(array, except: [:description])
|
||||
|
||||
expected = [{ name: 'Name 1' },
|
||||
{ name: 'Name 2' }]
|
||||
|
||||
assert_equal expected, serializer.serializable_array
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,18 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class ArraySerializer
|
||||
class KeyFormatTest < Minitest::Test
|
||||
def test_array_serializer_pass_options_to_items_serializers
|
||||
array = [WebLog.new({ name: 'Name 1', display_name: 'Display Name 1'}),
|
||||
WebLog.new({ name: 'Name 2', display_name: 'Display Name 2'})]
|
||||
serializer = ArraySerializer.new(array, key_format: :lower_camel)
|
||||
|
||||
expected = [{ name: 'Name 1', displayName: 'Display Name 1' },
|
||||
{ name: 'Name 2', displayName: 'Display Name 2' }]
|
||||
|
||||
assert_equal expected, serializer.serializable_array
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,53 +0,0 @@
|
||||
require 'test_helper'
|
||||
require 'active_model/serializer'
|
||||
|
||||
module ActiveModel
|
||||
class ArraySerializer
|
||||
class MetaTest < Minitest::Test
|
||||
def setup
|
||||
@profile1 = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
@profile2 = Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })
|
||||
@serializer = ArraySerializer.new([@profile1, @profile2], root: 'profiles')
|
||||
end
|
||||
|
||||
def test_meta
|
||||
@serializer.meta = { total: 10 }
|
||||
|
||||
assert_equal({
|
||||
'profiles' => [
|
||||
{
|
||||
name: 'Name 1',
|
||||
description: 'Description 1'
|
||||
}, {
|
||||
name: 'Name 2',
|
||||
description: 'Description 2'
|
||||
}
|
||||
],
|
||||
meta: {
|
||||
total: 10
|
||||
}
|
||||
}, @serializer.as_json)
|
||||
end
|
||||
|
||||
def test_meta_using_meta_key
|
||||
@serializer.meta_key = :my_meta
|
||||
@serializer.meta = { total: 10 }
|
||||
|
||||
assert_equal({
|
||||
'profiles' => [
|
||||
{
|
||||
name: 'Name 1',
|
||||
description: 'Description 1'
|
||||
}, {
|
||||
name: 'Name 2',
|
||||
description: 'Description 2'
|
||||
}
|
||||
],
|
||||
my_meta: {
|
||||
total: 10
|
||||
}
|
||||
}, @serializer.as_json)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,18 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class ArraySerializer
|
||||
class OnlyTest < Minitest::Test
|
||||
def test_array_serializer_pass_only_to_items_serializers
|
||||
array = [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }),
|
||||
Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })]
|
||||
serializer = ArraySerializer.new(array, only: [:name])
|
||||
|
||||
expected = [{ name: 'Name 1' },
|
||||
{ name: 'Name 2' }]
|
||||
|
||||
assert_equal expected, serializer.serializable_array
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,16 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class ArraySerializer
|
||||
class OptionsTest < Minitest::Test
|
||||
def test_custom_options_are_accessible_from_serializer
|
||||
|
||||
array = [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }),
|
||||
Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })]
|
||||
serializer = ArraySerializer.new(array, only: [:name], context: {foo: :bar})
|
||||
|
||||
assert_equal({foo: :bar}, serializer.context)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,102 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class ArraySerializer
|
||||
class RootAsOptionTest < Minitest::Test
|
||||
def setup
|
||||
@old_root = ArraySerializer._root
|
||||
@profile1 = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
@profile2 = Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })
|
||||
@serializer = ArraySerializer.new([@profile1, @profile2], root: :initialize)
|
||||
end
|
||||
|
||||
def teardown
|
||||
ArraySerializer._root = @old_root
|
||||
end
|
||||
|
||||
def test_root_is_not_displayed_using_serializable_array
|
||||
assert_equal([
|
||||
{ name: 'Name 1', description: 'Description 1' },
|
||||
{ name: 'Name 2', description: 'Description 2' }
|
||||
], @serializer.serializable_array)
|
||||
end
|
||||
|
||||
def test_root_using_as_json
|
||||
assert_equal({
|
||||
initialize: [
|
||||
{ name: 'Name 1', description: 'Description 1' },
|
||||
{ name: 'Name 2', description: 'Description 2' }
|
||||
]
|
||||
}, @serializer.as_json)
|
||||
end
|
||||
|
||||
def test_root_as_argument_takes_precedence
|
||||
assert_equal({
|
||||
argument: [
|
||||
{ name: 'Name 1', description: 'Description 1' },
|
||||
{ name: 'Name 2', description: 'Description 2' }
|
||||
]
|
||||
}, @serializer.as_json(root: :argument))
|
||||
end
|
||||
|
||||
def test_using_false_root_in_initialize_takes_precedence
|
||||
ArraySerializer._root = 'root'
|
||||
@serializer = ArraySerializer.new([@profile1, @profile2], root: false)
|
||||
|
||||
assert_equal([
|
||||
{ name: 'Name 1', description: 'Description 1' },
|
||||
{ name: 'Name 2', description: 'Description 2' }
|
||||
], @serializer.as_json)
|
||||
end
|
||||
end
|
||||
|
||||
class RootInSerializerTest < Minitest::Test
|
||||
def setup
|
||||
@old_root = ArraySerializer._root
|
||||
ArraySerializer._root = :in_serializer
|
||||
@profile1 = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
@profile2 = Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })
|
||||
@serializer = ArraySerializer.new([@profile1, @profile2])
|
||||
@rooted_serializer = ArraySerializer.new([@profile1, @profile2], root: :initialize)
|
||||
end
|
||||
|
||||
def teardown
|
||||
ArraySerializer._root = @old_root
|
||||
end
|
||||
|
||||
def test_root_is_not_displayed_using_serializable_hash
|
||||
assert_equal([
|
||||
{ name: 'Name 1', description: 'Description 1' },
|
||||
{ name: 'Name 2', description: 'Description 2' }
|
||||
], @serializer.serializable_array)
|
||||
end
|
||||
|
||||
def test_root_using_as_json
|
||||
assert_equal({
|
||||
in_serializer: [
|
||||
{ name: 'Name 1', description: 'Description 1' },
|
||||
{ name: 'Name 2', description: 'Description 2' }
|
||||
]
|
||||
}, @serializer.as_json)
|
||||
end
|
||||
|
||||
def test_root_in_initializer_takes_precedence
|
||||
assert_equal({
|
||||
initialize: [
|
||||
{ name: 'Name 1', description: 'Description 1' },
|
||||
{ name: 'Name 2', description: 'Description 2' }
|
||||
]
|
||||
}, @rooted_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_root_as_argument_takes_precedence
|
||||
assert_equal({
|
||||
argument: [
|
||||
{ name: 'Name 1', description: 'Description 1' },
|
||||
{ name: 'Name 2', description: 'Description 2' }
|
||||
]
|
||||
}, @rooted_serializer.as_json(root: :argument))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,24 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class ArraySerializer
|
||||
class ScopeTest < Minitest::Test
|
||||
def test_array_serializer_pass_options_to_items_serializers
|
||||
array = [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }),
|
||||
Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })]
|
||||
serializer = ArraySerializer.new(array, scope: current_user)
|
||||
|
||||
expected = [{ name: 'Name 1', description: 'Description 1 - user' },
|
||||
{ name: 'Name 2', description: 'Description 2 - user' }]
|
||||
|
||||
assert_equal expected, serializer.serializable_array
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_user
|
||||
'user'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,216 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class ArraySerializer
|
||||
class BasicObjectsSerializationTest < Minitest::Test
|
||||
def setup
|
||||
array = [1, 2, 3]
|
||||
@serializer = Serializer.serializer_for(array).new(array)
|
||||
end
|
||||
|
||||
def test_serializer_for_array_returns_appropriate_type
|
||||
assert_kind_of ActiveModel::ArraySerializer, @serializer
|
||||
end
|
||||
|
||||
def test_array_serializer_serializes_simple_objects
|
||||
assert_equal [1, 2, 3], @serializer.serializable_array
|
||||
assert_equal [1, 2, 3], @serializer.as_json
|
||||
end
|
||||
end
|
||||
|
||||
class CustomArraySerializerSupport < Minitest::Test
|
||||
def setup
|
||||
Object.const_set(:ArraySerializer, Class.new)
|
||||
|
||||
array = [1, 2, 3]
|
||||
@serializer_class = Serializer.serializer_for(array)
|
||||
end
|
||||
|
||||
def teardown
|
||||
Object.send(:remove_const, :ArraySerializer)
|
||||
end
|
||||
|
||||
def test_serializer_for_array_returns_appropriate_type
|
||||
assert_equal ::ArraySerializer, @serializer_class
|
||||
end
|
||||
end
|
||||
|
||||
class CustomSerializerClassTest < Minitest::Test
|
||||
def setup
|
||||
Object.const_set(:CustomSerializer, Class.new)
|
||||
end
|
||||
|
||||
def teardown
|
||||
Object.send(:remove_const, :CustomSerializer)
|
||||
end
|
||||
|
||||
def test_serializer_for_array_returns_appropriate_type
|
||||
object = {}
|
||||
def object.serializer_class; CustomSerializer; end
|
||||
|
||||
assert_equal CustomSerializer, Serializer.serializer_for(object)
|
||||
end
|
||||
end
|
||||
|
||||
class ModelSerializationTest < Minitest::Test
|
||||
def test_array_serializer_serializes_models
|
||||
array = [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }),
|
||||
Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })]
|
||||
serializer = ArraySerializer.new(array)
|
||||
|
||||
expected = [{ name: 'Name 1', description: 'Description 1' },
|
||||
{ name: 'Name 2', description: 'Description 2' }]
|
||||
|
||||
assert_equal expected, serializer.serializable_array
|
||||
assert_equal expected, serializer.as_json
|
||||
end
|
||||
|
||||
def test_array_serializers_each_serializer
|
||||
array = [::Model.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }),
|
||||
::Model.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })]
|
||||
serializer = ArraySerializer.new(array, each_serializer: ProfileSerializer)
|
||||
|
||||
expected = [{ name: 'Name 1', description: 'Description 1' },
|
||||
{ name: 'Name 2', description: 'Description 2' }]
|
||||
|
||||
assert_equal expected, serializer.serializable_array
|
||||
assert_equal expected, serializer.as_json
|
||||
end
|
||||
|
||||
def test_associated_objects_of_multiple_instances_embedded_in_root
|
||||
@association = PostSerializer._associations[:comments]
|
||||
@old_association = @association.dup
|
||||
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
|
||||
@post1 = Post.new({ title: 'Title 1', body: 'Body 1', date: '1/1/2000' })
|
||||
@post2 = Post.new({ title: 'Title 2', body: 'Body 2', date: '1/1/2000' })
|
||||
|
||||
class << @post2
|
||||
attr_writer :comments
|
||||
end
|
||||
|
||||
@post2.comments = [
|
||||
Comment.new(content: 'C3'),
|
||||
Comment.new(content: 'C4')
|
||||
]
|
||||
|
||||
@serializer = ArraySerializer.new([@post1, @post2], root: :posts)
|
||||
assert_equal({
|
||||
posts: [
|
||||
{title: "Title 1", body: "Body 1", "comment_ids" => @post1.comments.map(&:object_id) },
|
||||
{title: "Title 2", body: "Body 2", "comment_ids" => @post2.comments.map(&:object_id) }
|
||||
],
|
||||
'comments' => [
|
||||
{content: "C1"},
|
||||
{content: "C2"},
|
||||
{content: "C3"},
|
||||
{content: "C4"}
|
||||
]
|
||||
}, @serializer.as_json)
|
||||
ensure
|
||||
PostSerializer._associations[:comments] = @old_association
|
||||
end
|
||||
|
||||
def test_embed_object_for_has_one_association_with_nil_value
|
||||
@association = UserSerializer._associations[:profile]
|
||||
@old_association = @association.dup
|
||||
|
||||
@association.embed = :objects
|
||||
|
||||
@user1 = User.new({ name: 'User 1', email: 'email1@server.com' })
|
||||
@user2 = User.new({ name: 'User 2', email: 'email2@server.com' })
|
||||
|
||||
class << @user1
|
||||
def profile
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
class << @user2
|
||||
def profile
|
||||
@profile ||= Profile.new(name: 'Name 1', description: 'Desc 1')
|
||||
end
|
||||
end
|
||||
|
||||
@serializer = ArraySerializer.new([@user1, @user2]) #, root: :posts)
|
||||
assert_equal([
|
||||
{ name: "User 1", email: "email1@server.com", profile: nil },
|
||||
{ name: "User 2", email: "email2@server.com", profile: { name: 'Name 1', description: 'Desc 1' } }
|
||||
], @serializer.as_json)
|
||||
ensure
|
||||
UserSerializer._associations[:profile] = @old_association
|
||||
end
|
||||
|
||||
def test_embed_object_in_root_for_has_one_association_with_nil_value
|
||||
@association = UserSerializer._associations[:profile]
|
||||
@old_association = @association.dup
|
||||
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
|
||||
@user1 = User.new({ name: 'User 1', email: 'email1@server.com' })
|
||||
@user2 = User.new({ name: 'User 2', email: 'email2@server.com' })
|
||||
|
||||
class << @user1
|
||||
def profile
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
class << @user2
|
||||
def profile
|
||||
@profile ||= Profile.new(name: 'Name 1', description: 'Desc 1')
|
||||
end
|
||||
end
|
||||
|
||||
@serializer = ArraySerializer.new([@user1, @user2], root: :users)
|
||||
assert_equal({
|
||||
users: [
|
||||
{ name: "User 1", email: "email1@server.com", 'profile_id' => nil },
|
||||
{ name: "User 2", email: "email2@server.com", 'profile_id' => @user2.profile.object_id }
|
||||
],
|
||||
'profiles' => [
|
||||
{ name: 'Name 1', description: 'Desc 1' }
|
||||
]
|
||||
}, @serializer.as_json)
|
||||
ensure
|
||||
UserSerializer._associations[:profile] = @old_association
|
||||
end
|
||||
|
||||
def test_embed_object_in_root_for_has_one_association_with_all_nil_values
|
||||
@association = UserSerializer._associations[:profile]
|
||||
@old_association = @association.dup
|
||||
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
|
||||
@user1 = User.new({ name: 'User 1', email: 'email1@server.com' })
|
||||
@user2 = User.new({ name: 'User 2', email: 'email2@server.com' })
|
||||
|
||||
class << @user1
|
||||
def profile
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
class << @user2
|
||||
def profile
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
@serializer = ArraySerializer.new([@user1, @user2], root: :users)
|
||||
assert_equal({
|
||||
users: [
|
||||
{ name: "User 1", email: "email1@server.com", 'profile_id' => nil },
|
||||
{ name: "User 2", email: "email2@server.com", 'profile_id' => nil }
|
||||
]
|
||||
}, @serializer.as_json)
|
||||
ensure
|
||||
UserSerializer._associations[:profile] = @old_association
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,13 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class DefaultSerializer
|
||||
class Test < Minitest::Test
|
||||
def test_serialize_objects
|
||||
assert_equal(nil, DefaultSerializer.new(nil).serializable_object)
|
||||
assert_equal(1, DefaultSerializer.new(1).serializable_object)
|
||||
assert_equal('hi', DefaultSerializer.new('hi').serializable_object)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,36 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class Association
|
||||
class BuildSerializerTest < Minitest::Test
|
||||
def setup
|
||||
@association = Association::HasOne.new('post', serializer: PostSerializer)
|
||||
@post = Post.new({ title: 'Title 1', body: 'Body 1', date: '1/1/2000' })
|
||||
@user = User.new
|
||||
end
|
||||
|
||||
def test_build_serializer_for_array_called_twice
|
||||
2.times do
|
||||
serializer = @association.build_serializer(@post)
|
||||
assert_instance_of(PostSerializer, serializer)
|
||||
end
|
||||
end
|
||||
|
||||
def test_build_serializer_from_in_a_namespace
|
||||
assoc = Association::HasOne.new('profile')
|
||||
serializer = TestNamespace::UserSerializer.new(@user).build_serializer(assoc)
|
||||
|
||||
assert_instance_of(TestNamespace::ProfileSerializer, serializer)
|
||||
end
|
||||
|
||||
def test_build_serializer_with_prefix
|
||||
assoc = Association::HasOne.new('profile', prefix: :short)
|
||||
serializer = UserSerializer.new(@user).build_serializer(assoc)
|
||||
|
||||
assert_instance_of(ShortProfileSerializer, serializer)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,49 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class AssociationsTest < Minitest::Test
|
||||
def test_associations_inheritance
|
||||
inherited_serializer_klass = Class.new(PostSerializer) do
|
||||
has_many :users
|
||||
end
|
||||
another_inherited_serializer_klass = Class.new(PostSerializer)
|
||||
|
||||
assert_equal([:comments, :users],
|
||||
inherited_serializer_klass._associations.keys)
|
||||
assert_equal([:comments],
|
||||
another_inherited_serializer_klass._associations.keys)
|
||||
end
|
||||
def test_multiple_nested_associations
|
||||
parent = SelfReferencingUserParent.new(name: "The Parent")
|
||||
child = SelfReferencingUser.new(name: "The child", parent: parent)
|
||||
self_referencing_user_serializer = SelfReferencingUserSerializer.new(child)
|
||||
result = self_referencing_user_serializer.as_json
|
||||
expected_result = {
|
||||
"self_referencing_user"=>{
|
||||
:name=>"The child",
|
||||
"type_id"=>child.type.object_id,
|
||||
"parent_id"=>child.parent.object_id
|
||||
|
||||
},
|
||||
"types"=>[
|
||||
{
|
||||
:name=>"N1",
|
||||
},
|
||||
{
|
||||
:name=>"N2",
|
||||
}
|
||||
],
|
||||
"parents"=>[
|
||||
{
|
||||
:name=>"N1",
|
||||
"type_id"=>child.parent.type.object_id,
|
||||
"parent_id"=>nil
|
||||
}
|
||||
]
|
||||
}
|
||||
assert_equal(expected_result, result)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,57 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class AttributesTest < Minitest::Test
|
||||
def setup
|
||||
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
@profile_serializer = ProfileSerializer.new(@profile)
|
||||
end
|
||||
|
||||
def test_attributes_definition
|
||||
assert_equal([:name, :description],
|
||||
@profile_serializer.class._attributes)
|
||||
end
|
||||
|
||||
def test_attributes_serialization_using_serializable_hash
|
||||
assert_equal({
|
||||
name: 'Name 1', description: 'Description 1'
|
||||
}, @profile_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_attributes_serialization_using_as_json
|
||||
assert_equal({
|
||||
'profile' => { name: 'Name 1', description: 'Description 1' }
|
||||
}, @profile_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_attributes_inheritance
|
||||
inherited_serializer_klass = Class.new(ProfileSerializer) do
|
||||
attributes :comments
|
||||
end
|
||||
another_inherited_serializer_klass = Class.new(ProfileSerializer)
|
||||
|
||||
assert_equal([:name, :description, :comments],
|
||||
inherited_serializer_klass._attributes)
|
||||
assert_equal([:name, :description],
|
||||
another_inherited_serializer_klass._attributes)
|
||||
end
|
||||
|
||||
def tests_query_attributes_strip_question_mark
|
||||
model = Class.new(::Model) do
|
||||
def strip?
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
serializer = Class.new(ActiveModel::Serializer) do
|
||||
attributes :strip?
|
||||
end
|
||||
|
||||
actual = serializer.new(model.new).as_json
|
||||
|
||||
assert_equal({ strip: true }, actual)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,91 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class Config
|
||||
class Test < Minitest::Test
|
||||
def test_config_const_is_an_instance_of_config
|
||||
assert_kind_of Config, CONFIG
|
||||
end
|
||||
|
||||
def test_config_instance
|
||||
config = Config.new
|
||||
config.setting1 = 'value1'
|
||||
|
||||
assert_equal 'value1', config.setting1
|
||||
end
|
||||
|
||||
def test_each_config
|
||||
config = Config.new
|
||||
config.setting1 = 'value1'
|
||||
config.setting2 = 'value2'
|
||||
|
||||
actual = {}
|
||||
|
||||
config.each do |k, v|
|
||||
actual[k] = v
|
||||
end
|
||||
|
||||
assert_equal({ 'setting1' => 'value1', 'setting2' => 'value2' }, actual)
|
||||
end
|
||||
end
|
||||
|
||||
class ConfigTest < Minitest::Test
|
||||
def test_setup
|
||||
Serializer.setup do |config|
|
||||
config.a = 'v1'
|
||||
config.b = 'v2'
|
||||
end
|
||||
|
||||
assert_equal 'v1', CONFIG.a
|
||||
assert_equal 'v2', CONFIG.b
|
||||
ensure
|
||||
CONFIG.clear
|
||||
end
|
||||
|
||||
def test_config_accessors
|
||||
Serializer.setup do |config|
|
||||
config.foo = 'v1'
|
||||
config.bar = 'v2'
|
||||
end
|
||||
|
||||
assert_equal 'v1', CONFIG.foo
|
||||
assert_equal 'v2', CONFIG.bar
|
||||
ensure
|
||||
CONFIG.clear
|
||||
end
|
||||
|
||||
def test_acessor_when_nil
|
||||
assert_nil CONFIG.foo
|
||||
CONFIG.foo = 1
|
||||
assert_equal 1, CONFIG.foo
|
||||
assert_nil CONFIG.bar
|
||||
end
|
||||
end
|
||||
|
||||
class ApplyConfigTest < Minitest::Test
|
||||
def test_apply_config_to_associations
|
||||
CONFIG.embed = :ids
|
||||
CONFIG.embed_in_root = true
|
||||
CONFIG.key_format = :lower_camel
|
||||
|
||||
association = PostSerializer._associations[:comments]
|
||||
old_association = association.dup
|
||||
|
||||
association.send :initialize, association.name, association.options
|
||||
|
||||
assert association.embed_ids?
|
||||
assert !association.embed_objects?
|
||||
assert association.embed_in_root
|
||||
assert_equal :lower_camel, association.key_format
|
||||
assert_equal 'post', PostSerializer.root_name
|
||||
CONFIG.plural_default_root = true
|
||||
assert_equal 'posts', PostSerializer.root_name
|
||||
ensure
|
||||
PostSerializer._associations[:comments] = old_association
|
||||
CONFIG.clear
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,69 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class FilterOptionsTest < Minitest::Test
|
||||
def setup
|
||||
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
end
|
||||
|
||||
def test_only_option
|
||||
@profile_serializer = ProfileSerializer.new(@profile, only: :name)
|
||||
assert_equal({
|
||||
'profile' => { name: 'Name 1' }
|
||||
}, @profile_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_except_option
|
||||
@profile_serializer = ProfileSerializer.new(@profile, except: :comments)
|
||||
assert_equal({
|
||||
'profile' => { name: 'Name 1', description: 'Description 1' }
|
||||
}, @profile_serializer.as_json)
|
||||
end
|
||||
end
|
||||
|
||||
class FilterAttributesTest < Minitest::Test
|
||||
def setup
|
||||
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
@profile_serializer = ProfileSerializer.new(@profile)
|
||||
@profile_serializer.instance_eval do
|
||||
def filter(keys)
|
||||
keys - [:description]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_filtered_attributes_serialization
|
||||
assert_equal({
|
||||
'profile' => { name: 'Name 1' }
|
||||
}, @profile_serializer.as_json)
|
||||
end
|
||||
end
|
||||
|
||||
class FilterAssociationsTest < Minitest::Test
|
||||
def setup
|
||||
@association = PostSerializer._associations[:comments]
|
||||
@old_association = @association.dup
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
@post = Post.new({ title: 'Title 1', body: 'Body 1', date: '1/1/2000' })
|
||||
@post_serializer = PostSerializer.new(@post)
|
||||
@post_serializer.instance_eval do
|
||||
def filter(keys)
|
||||
keys - [:body, :comments]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def teardown
|
||||
PostSerializer._associations[:comments] = @old_association
|
||||
end
|
||||
|
||||
def test_filtered_associations_serialization
|
||||
assert_equal({
|
||||
'post' => { title: 'Title 1' }
|
||||
}, @post_serializer.as_json)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,189 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class HasManyPolymorphicTest < ActiveModel::TestCase
|
||||
def setup
|
||||
@association = MailSerializer._associations[:attachments]
|
||||
@old_association = @association.dup
|
||||
|
||||
@mail = Mail.new({ body: 'Body 1' })
|
||||
@mail_serializer = MailSerializer.new(@mail)
|
||||
end
|
||||
|
||||
def teardown
|
||||
MailSerializer._associations[:attachments] = @old_association
|
||||
end
|
||||
|
||||
def model_name(object)
|
||||
object.class.to_s.demodulize.underscore.to_sym
|
||||
end
|
||||
|
||||
def test_associations_definition
|
||||
assert_equal 1, MailSerializer._associations.length
|
||||
assert_kind_of Association::HasMany, @association
|
||||
assert_equal true, @association.polymorphic
|
||||
assert_equal 'attachments', @association.name
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_serialization_using_serializable_hash
|
||||
@association.embed = :ids
|
||||
|
||||
assert_equal({
|
||||
body: 'Body 1',
|
||||
'attachment_ids' => @mail.attachments.map do |c|
|
||||
{ id: c.object_id, type: model_name(c) }
|
||||
end
|
||||
}, @mail_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_serialization_using_as_json
|
||||
@association.embed = :ids
|
||||
|
||||
assert_equal({
|
||||
'mail' => {
|
||||
:body => 'Body 1',
|
||||
'attachment_ids' => @mail.attachments.map do |c|
|
||||
{ id: c.object_id, type: model_name(c) }
|
||||
end
|
||||
}
|
||||
}, @mail_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_serialization_using_serializable_hash_and_key_from_options
|
||||
@association.embed = :ids
|
||||
@association.key = 'key'
|
||||
|
||||
assert_equal({
|
||||
body: 'Body 1',
|
||||
'key' => @mail.attachments.map do |c|
|
||||
{ id: c.object_id, type: model_name(c) }
|
||||
end
|
||||
}, @mail_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_serialization_using_serializable_hash
|
||||
@association.embed = :objects
|
||||
|
||||
assert_equal({
|
||||
body: 'Body 1',
|
||||
:attachments => [
|
||||
{ type: :image, image: { url: 'U1' }},
|
||||
{ type: :video, video: { html: 'H1' }}
|
||||
]
|
||||
}, @mail_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_serialization_using_as_json
|
||||
@association.embed = :objects
|
||||
|
||||
assert_equal({
|
||||
'mail' => {
|
||||
body: 'Body 1',
|
||||
attachments: [
|
||||
{ type: :image, image: { url: 'U1' }},
|
||||
{ type: :video, video: { html: 'H1' }}
|
||||
]
|
||||
}
|
||||
}, @mail_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_nil_objects_serialization_using_as_json
|
||||
@association.embed = :objects
|
||||
@mail.instance_eval do
|
||||
def attachments
|
||||
[nil]
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
'mail' => {
|
||||
:body => 'Body 1',
|
||||
:attachments => [nil]
|
||||
}
|
||||
}, @mail_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_serialization_using_serializable_hash_and_root_from_options
|
||||
@association.embed = :objects
|
||||
@association.embedded_key = 'root'
|
||||
|
||||
assert_equal({
|
||||
body: 'Body 1',
|
||||
'root' => [
|
||||
{ type: :image, image: { url: 'U1' }},
|
||||
{ type: :video, video: { html: 'H1' }}
|
||||
]
|
||||
}, @mail_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_including_objects_serialization_using_serializable_hash
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
|
||||
assert_equal({
|
||||
body: 'Body 1',
|
||||
'attachment_ids' => @mail.attachments.map do |c|
|
||||
{ id: c.object_id, type: model_name(c) }
|
||||
end
|
||||
}, @mail_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_including_objects_serialization_using_as_json
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
|
||||
assert_equal({
|
||||
'mail' => {
|
||||
body: 'Body 1',
|
||||
'attachment_ids' => @mail.attachments.map do |c|
|
||||
{ id: c.object_id, type: model_name(c) }
|
||||
end,
|
||||
},
|
||||
'attachments' => [
|
||||
{ type: :image, image: { url: 'U1' }},
|
||||
{ type: :video, video: { html: 'H1' }}
|
||||
]
|
||||
}, @mail_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_nothing_including_objects_serialization_using_as_json
|
||||
@association.embed = nil
|
||||
@association.embed_in_root = true
|
||||
|
||||
assert_equal({
|
||||
'mail' => { body: 'Body 1' },
|
||||
'attachments' => [
|
||||
{ type: :image, image: { url: 'U1' }},
|
||||
{ type: :video, video: { html: 'H1' }}
|
||||
]
|
||||
}, @mail_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_using_a_given_serializer
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
@association.serializer_from_options = Class.new(ActiveModel::Serializer) do
|
||||
def fake
|
||||
'fake'
|
||||
end
|
||||
|
||||
attributes :fake
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
'mail' => {
|
||||
body: 'Body 1',
|
||||
'attachment_ids' => @mail.attachments.map do |c|
|
||||
{ id: c.object_id, type: model_name(c) }
|
||||
end
|
||||
},
|
||||
'attachments' => [
|
||||
{ type: :image, image: { fake: 'fake' }},
|
||||
{ type: :video, video: { fake: 'fake' }}
|
||||
]
|
||||
}, @mail_serializer.as_json)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,265 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class HasManyTest < Minitest::Test
|
||||
def setup
|
||||
@association = PostSerializer._associations[:comments]
|
||||
@old_association = @association.dup
|
||||
|
||||
@post = Post.new({ title: 'Title 1', body: 'Body 1', date: '1/1/2000' })
|
||||
@post_serializer = PostSerializer.new(@post)
|
||||
end
|
||||
|
||||
def teardown
|
||||
PostSerializer._associations[:comments] = @old_association
|
||||
end
|
||||
|
||||
def test_associations_definition
|
||||
assert_equal 1, PostSerializer._associations.length
|
||||
assert_kind_of Association::HasMany, @association
|
||||
assert_equal 'comments', @association.name
|
||||
end
|
||||
|
||||
def test_associations_inheritance
|
||||
inherited_serializer_klass = Class.new(PostSerializer) do
|
||||
has_many :some_associations
|
||||
end
|
||||
another_inherited_serializer_klass = Class.new(PostSerializer)
|
||||
|
||||
assert_equal(PostSerializer._associations.length + 1,
|
||||
inherited_serializer_klass._associations.length)
|
||||
assert_equal(PostSerializer._associations.length,
|
||||
another_inherited_serializer_klass._associations.length)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_serialization_using_serializable_hash
|
||||
@association.embed = :ids
|
||||
|
||||
assert_equal({
|
||||
title: 'Title 1', body: 'Body 1', 'comment_ids' => @post.comments.map { |c| c.object_id }
|
||||
}, @post_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_serialization_using_as_json
|
||||
@association.embed = :ids
|
||||
|
||||
assert_equal({
|
||||
'post' => { title: 'Title 1', body: 'Body 1', 'comment_ids' => @post.comments.map { |c| c.object_id } }
|
||||
}, @post_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_serialization_using_serializable_hash_and_key_from_options
|
||||
@association.embed = :ids
|
||||
@association.key = 'key'
|
||||
|
||||
assert_equal({
|
||||
title: 'Title 1', body: 'Body 1', 'key' => @post.comments.map { |c| c.object_id }
|
||||
}, @post_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_serialization_using_serializable_hash
|
||||
@association.embed = :objects
|
||||
|
||||
assert_equal({
|
||||
title: 'Title 1', body: 'Body 1', comments: [{ content: 'C1' }, { content: 'C2' }]
|
||||
}, @post_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_serialization_using_as_json
|
||||
@association.embed = :objects
|
||||
|
||||
assert_equal({
|
||||
'post' => { title: 'Title 1', body: 'Body 1', comments: [{ content: 'C1' }, { content: 'C2' }] }
|
||||
}, @post_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_nil_objects_serialization_using_as_json
|
||||
@association.embed = :objects
|
||||
@post.instance_eval do
|
||||
def comments
|
||||
[nil]
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
'post' => { title: 'Title 1', body: 'Body 1', comments: [nil] }
|
||||
}, @post_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_serialization_using_serializable_hash_and_root_from_options
|
||||
@association.embed = :objects
|
||||
@association.embedded_key = 'root'
|
||||
|
||||
assert_equal({
|
||||
title: 'Title 1', body: 'Body 1', 'root' => [{ content: 'C1' }, { content: 'C2' }]
|
||||
}, @post_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_including_objects_serialization_using_serializable_hash
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
|
||||
assert_equal({
|
||||
title: 'Title 1', body: 'Body 1', 'comment_ids' => @post.comments.map { |c| c.object_id }
|
||||
}, @post_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_including_objects_serialization_using_as_json
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
|
||||
assert_equal({
|
||||
'post' => { title: 'Title 1', body: 'Body 1', 'comment_ids' => @post.comments.map { |c| c.object_id } },
|
||||
'comments' => [{ content: 'C1' }, { content: 'C2' }]
|
||||
}, @post_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_including_objects_serialization_when_invoked_from_parent_serializer
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
|
||||
category = Category.new(name: 'Name 1')
|
||||
category.instance_variable_set(:@posts, [@post])
|
||||
category_serializer = CategorySerializer.new(category)
|
||||
|
||||
assert_equal({
|
||||
'category' => {
|
||||
name: 'Name 1',
|
||||
posts: [{ title: 'Title 1', body: 'Body 1', 'comment_ids' => @post.comments.map { |c| c.object_id } }]
|
||||
},
|
||||
"comments" => [{ content: 'C1' }, { content: 'C2' }]
|
||||
}, category_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_nothing_including_objects_serialization_using_as_json
|
||||
@association.embed = nil
|
||||
@association.embed_in_root = true
|
||||
|
||||
assert_equal({
|
||||
'post' => { title: 'Title 1', body: 'Body 1' },
|
||||
'comments' => [{ content: 'C1' }, { content: 'C2' }]
|
||||
}, @post_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_using_a_given_serializer
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
@association.serializer_from_options = Class.new(Serializer) do
|
||||
def content
|
||||
object.read_attribute_for_serialization(:content) + '!'
|
||||
end
|
||||
|
||||
attributes :content
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
'post' => { title: 'Title 1', body: 'Body 1', 'comment_ids' => @post.comments.map { |c| c.object_id } },
|
||||
'comments' => [{ content: 'C1!' }, { content: 'C2!' }]
|
||||
}, @post_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_using_a_given_array_serializer
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
@association.serializer_from_options = Class.new(ArraySerializer) do
|
||||
def serializable_object
|
||||
{ my_content: ['fake'] }
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
'post' => { title: 'Title 1', body: 'Body 1', 'comment_ids' => @post.comments.map { |c| c.object_id } },
|
||||
'comments' => { my_content: ['fake'] }
|
||||
}, @post_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_using_a_given_array_serializer
|
||||
@association.serializer_from_options = Class.new(ArraySerializer) do
|
||||
def serializable_object(options={})
|
||||
{ my_content: ['fake'] }
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
'post' => { title: 'Title 1', body: 'Body 1', comments: { my_content: ['fake'] } }
|
||||
}, @post_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_including_objects_serialization_with_embed_in_root_key
|
||||
@association.embed_in_root = true
|
||||
@association.embed_in_root_key = :linked
|
||||
@association.embed = :ids
|
||||
assert_equal({
|
||||
'post' => {
|
||||
title: 'Title 1', body: 'Body 1',
|
||||
'comment_ids' => @post.comments.map(&:object_id)
|
||||
},
|
||||
linked: {
|
||||
'comments' => [
|
||||
{ content: 'C1' },
|
||||
{ content: 'C2' }
|
||||
]
|
||||
},
|
||||
}, @post_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_using_embed_namespace_including_object_serialization_with_embed_in_root_key
|
||||
@association.embed_in_root = true
|
||||
@association.embed_in_root_key = :linked
|
||||
@association.embed = :ids
|
||||
@association.embed_namespace = :links
|
||||
@association.key = :comments
|
||||
assert_equal({
|
||||
'post' => {
|
||||
title: 'Title 1', body: 'Body 1',
|
||||
links: {
|
||||
comments: @post.comments.map(&:object_id)
|
||||
}
|
||||
},
|
||||
linked: {
|
||||
'comments' => [
|
||||
{ content: 'C1' },
|
||||
{ content: 'C2' }
|
||||
]
|
||||
},
|
||||
}, @post_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_using_embed_namespace
|
||||
@association.embed = :objects
|
||||
@association.embed_namespace = :links
|
||||
|
||||
assert_equal({
|
||||
'post' => {
|
||||
title: 'Title 1', body: 'Body 1',
|
||||
links: {
|
||||
comments: [
|
||||
{ content: 'C1' },
|
||||
{ content: 'C2' }
|
||||
]
|
||||
}
|
||||
}
|
||||
}, @post_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_name_key_embedding_ids_serialization_using_serializable_hash
|
||||
@association = NameKeyPostSerializer._associations[:comments]
|
||||
@association.embed = :ids
|
||||
|
||||
assert_equal({
|
||||
title: 'Title 1', body: 'Body 1', 'comments' => @post.comments.map { |c| c.object_id }
|
||||
}, NameKeyPostSerializer.new(@post).serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_name_key_embedding_ids_serialization_using_as_json
|
||||
@association = NameKeyPostSerializer._associations[:comments]
|
||||
@association.embed = :ids
|
||||
|
||||
assert_equal({
|
||||
'name_key_post' => { title: 'Title 1', body: 'Body 1', 'comments' => @post.comments.map { |c| c.object_id } }
|
||||
}, NameKeyPostSerializer.new(@post).as_json)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,27 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class HasOneAndHasManyTest < Minitest::Test
|
||||
def setup
|
||||
@post = SpecialPost.new({ title: 'T1', body: 'B1'})
|
||||
@post_serializer = SpecialPostSerializer.new(@post)
|
||||
end
|
||||
|
||||
def teardown
|
||||
end
|
||||
|
||||
def test_side_load_has_one_and_has_many_in_same_array
|
||||
assert_equal({
|
||||
"post" => {
|
||||
title: 'T1',
|
||||
body: 'B1',
|
||||
'comment_ids' => @post.comments.map { |c| c.object_id },
|
||||
'special_comment_id' => @post_serializer.special_comment.object_id,
|
||||
},
|
||||
"comments" => [{ content: 'C1' }, { content: 'C2' }, { content: 'special' }]
|
||||
}, @post_serializer.as_json(root: 'post'))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,196 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class HasOnePolymorphicTest < ActiveModel::TestCase
|
||||
def setup
|
||||
@association = InterviewSerializer._associations[:attachment]
|
||||
@old_association = @association.dup
|
||||
|
||||
@interview = Interview.new({ text: 'Text 1' })
|
||||
@interview_serializer = InterviewSerializer.new(@interview)
|
||||
end
|
||||
|
||||
def teardown
|
||||
InterviewSerializer._associations[:attachment] = @old_association
|
||||
end
|
||||
|
||||
def model_name(object)
|
||||
object.class.to_s.demodulize.underscore.to_sym
|
||||
end
|
||||
|
||||
def test_associations_definition
|
||||
assert_equal 1, InterviewSerializer._associations.length
|
||||
assert_kind_of Association::HasOne, @association
|
||||
assert_equal true, @association.polymorphic
|
||||
assert_equal 'attachment', @association.name
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_serialization_using_serializable_hash
|
||||
@association.embed = :ids
|
||||
|
||||
assert_equal({
|
||||
text: 'Text 1',
|
||||
'attachment_id' => {
|
||||
type: model_name(@interview.attachment),
|
||||
id: @interview.attachment.object_id
|
||||
}
|
||||
}, @interview_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_serialization_using_as_json
|
||||
@association.embed = :ids
|
||||
|
||||
assert_equal({
|
||||
'interview' => {
|
||||
text: 'Text 1',
|
||||
'attachment_id' => {
|
||||
type: model_name(@interview.attachment),
|
||||
id: @interview.attachment.object_id
|
||||
}
|
||||
}
|
||||
}, @interview_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_serialization_using_serializable_hash_and_key_from_options
|
||||
@association.embed = :ids
|
||||
@association.key = 'key'
|
||||
|
||||
assert_equal({
|
||||
text: 'Text 1',
|
||||
'key' => {
|
||||
type: model_name(@interview.attachment),
|
||||
id: @interview.attachment.object_id
|
||||
}
|
||||
}, @interview_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_serialization_using_serializable_hash
|
||||
@association.embed = :objects
|
||||
|
||||
assert_equal({
|
||||
text: 'Text 1',
|
||||
attachment: {
|
||||
type: model_name(@interview.attachment),
|
||||
model_name(@interview.attachment) => { url: 'U1'}
|
||||
}
|
||||
}, @interview_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_serialization_using_as_json
|
||||
@association.embed = :objects
|
||||
|
||||
assert_equal({
|
||||
'interview' => {
|
||||
text: 'Text 1',
|
||||
attachment: {
|
||||
type: model_name(@interview.attachment),
|
||||
model_name(@interview.attachment) => { url: 'U1'}
|
||||
}
|
||||
}
|
||||
}, @interview_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_nil_ids_serialization_using_as_json
|
||||
@association.embed = :ids
|
||||
@interview.instance_eval do
|
||||
def attachment
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
'interview' => { text: 'Text 1', 'attachment_id' => nil }
|
||||
}, @interview_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_nil_objects_serialization_using_as_json
|
||||
@association.embed = :objects
|
||||
@interview.instance_eval do
|
||||
def attachment
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
'interview' => { text: 'Text 1', attachment: nil }
|
||||
}, @interview_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_serialization_using_serializable_hash_and_root_from_options
|
||||
@association.embed = :objects
|
||||
@association.embedded_key = 'root'
|
||||
|
||||
assert_equal({
|
||||
text: 'Text 1',
|
||||
'root' => {
|
||||
type: model_name(@interview.attachment),
|
||||
model_name(@interview.attachment) => { url: 'U1'}
|
||||
}
|
||||
}, @interview_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_including_objects_serialization_using_serializable_hash
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
|
||||
assert_equal({
|
||||
text: 'Text 1',
|
||||
'attachment_id' => {
|
||||
type: model_name(@interview.attachment),
|
||||
id: @interview.attachment.object_id
|
||||
}
|
||||
}, @interview_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_including_objects_serialization_using_as_json
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
|
||||
assert_equal({
|
||||
'interview' => {
|
||||
text: 'Text 1',
|
||||
'attachment_id' => {
|
||||
type: model_name(@interview.attachment),
|
||||
id: @interview.attachment.object_id
|
||||
}
|
||||
},
|
||||
"attachments" => [{
|
||||
type: model_name(@interview.attachment),
|
||||
model_name(@interview.attachment) => {
|
||||
url: 'U1'
|
||||
}
|
||||
}]
|
||||
}, @interview_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_using_a_given_serializer
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
@association.serializer_from_options = Class.new(ActiveModel::Serializer) do
|
||||
def name
|
||||
'fake'
|
||||
end
|
||||
|
||||
attributes :name
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
'interview' => {
|
||||
text: 'Text 1',
|
||||
'attachment_id' => {
|
||||
type: model_name(@interview.attachment),
|
||||
id: @interview.attachment.object_id
|
||||
}
|
||||
},
|
||||
"attachments" => [{
|
||||
type: model_name(@interview.attachment),
|
||||
model_name(@interview.attachment) => {
|
||||
name: 'fake'
|
||||
}
|
||||
}]
|
||||
}, @interview_serializer.as_json)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,253 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class HasOneTest < Minitest::Test
|
||||
def setup
|
||||
@association = UserSerializer._associations[:profile]
|
||||
@old_association = @association.dup
|
||||
|
||||
@user = User.new({ name: 'Name 1', email: 'mail@server.com', gender: 'M' })
|
||||
@user_serializer = UserSerializer.new(@user)
|
||||
end
|
||||
|
||||
def teardown
|
||||
UserSerializer._associations[:profile] = @old_association
|
||||
end
|
||||
|
||||
def test_associations_definition
|
||||
assert_equal 1, UserSerializer._associations.length
|
||||
assert_kind_of Association::HasOne, @association
|
||||
assert_equal 'profile', @association.name
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_serialization_using_serializable_hash
|
||||
@association.embed = :ids
|
||||
|
||||
assert_equal({
|
||||
name: 'Name 1', email: 'mail@server.com', 'profile_id' => @user.profile.object_id
|
||||
}, @user_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_serialization_using_as_json
|
||||
@association.embed = :ids
|
||||
|
||||
assert_equal({
|
||||
'user' => { name: 'Name 1', email: 'mail@server.com', 'profile_id' => @user.profile.object_id }
|
||||
}, @user_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_serialization_using_serializable_hash_and_key_from_options
|
||||
@association.embed = :ids
|
||||
@association.key = 'key'
|
||||
|
||||
assert_equal({
|
||||
name: 'Name 1', email: 'mail@server.com', 'key' => @user.profile.object_id
|
||||
}, @user_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_serialization_using_serializable_hash
|
||||
@association.embed = :objects
|
||||
|
||||
assert_equal({
|
||||
name: 'Name 1', email: 'mail@server.com', profile: { name: 'N1', description: 'D1' }
|
||||
}, @user_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_serialization_using_as_json
|
||||
@association.embed = :objects
|
||||
|
||||
assert_equal({
|
||||
'user' => { name: 'Name 1', email: 'mail@server.com', profile: { name: 'N1', description: 'D1' } }
|
||||
}, @user_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_nil_ids_serialization_using_as_json
|
||||
@association.embed = :ids
|
||||
@user.instance_eval do
|
||||
def profile
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
'user' => { name: 'Name 1', email: 'mail@server.com', 'profile_id' => nil }
|
||||
}, @user_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_nil_objects_serialization_using_as_json
|
||||
@association.embed = :objects
|
||||
@user.instance_eval do
|
||||
def profile
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
'user' => { name: 'Name 1', email: 'mail@server.com', profile: nil }
|
||||
}, @user_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_serialization_using_serializable_hash_and_root_from_options
|
||||
@association.embed = :objects
|
||||
@association.embedded_key = 'root'
|
||||
|
||||
assert_equal({
|
||||
name: 'Name 1', email: 'mail@server.com', 'root' => { name: 'N1', description: 'D1' }
|
||||
}, @user_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_including_objects_serialization_using_serializable_hash
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
|
||||
assert_equal({
|
||||
name: 'Name 1', email: 'mail@server.com', 'profile_id' => @user.profile.object_id
|
||||
}, @user_serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_embedding_nil_ids_including_objects_serialization_using_as_json
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
@user.instance_eval do
|
||||
def profile
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
'user' => { name: 'Name 1', email: 'mail@server.com', 'profile_id' => nil },
|
||||
'profiles' => []
|
||||
}, @user_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_including_objects_serialization_using_as_json
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
|
||||
assert_equal({
|
||||
'user' => { name: 'Name 1', email: 'mail@server.com', 'profile_id' => @user.profile.object_id },
|
||||
'profiles' => [{ name: 'N1', description: 'D1' }]
|
||||
}, @user_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_including_objects_serialization_when_invoked_from_parent_serializer
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
|
||||
user_info = UserInfo.new
|
||||
user_info.instance_variable_set(:@user, @user)
|
||||
user_info_serializer = UserInfoSerializer.new(user_info)
|
||||
|
||||
assert_equal({
|
||||
'user_info' => { user: { name: 'Name 1', email: 'mail@server.com', 'profile_id' => @user.profile.object_id } },
|
||||
'profiles' => [{ name: 'N1', description: 'D1' }]
|
||||
}, user_info_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_using_a_given_serializer
|
||||
@association.embed = :ids
|
||||
@association.embed_in_root = true
|
||||
@association.serializer_from_options = Class.new(Serializer) do
|
||||
def name
|
||||
'fake'
|
||||
end
|
||||
|
||||
attributes :name
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
'user' => { name: 'Name 1', email: 'mail@server.com', 'profile_id' => @user.profile.object_id },
|
||||
'profiles' => [{ name: 'fake' }]
|
||||
}, @user_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_using_a_given_serializer
|
||||
@association.serializer_from_options = Class.new(Serializer) do
|
||||
def name
|
||||
'fake'
|
||||
end
|
||||
|
||||
attributes :name
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
'user' => { name: 'Name 1', email: 'mail@server.com', profile: { name: 'fake' } }
|
||||
}, @user_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_objects_with_nil_values
|
||||
user_info = UserInfo.new
|
||||
user_info.instance_eval do
|
||||
def user
|
||||
nil
|
||||
end
|
||||
end
|
||||
user_info_serializer = UserInfoSerializer.new(user_info)
|
||||
|
||||
assert_equal({
|
||||
'user_info' => { user: nil }
|
||||
}, user_info_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_using_embed_namespace
|
||||
@association.embed_namespace = :links
|
||||
@association.embed = :ids
|
||||
@association.key = :profile
|
||||
assert_equal({
|
||||
'user' => {
|
||||
name: 'Name 1', email: 'mail@server.com',
|
||||
links: {
|
||||
profile: @user.profile.object_id
|
||||
}
|
||||
}
|
||||
}, @user_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_asociations_embedding_objects_using_embed_namespace
|
||||
@association.embed_namespace = :links
|
||||
@association.embed = :objects
|
||||
assert_equal({
|
||||
'user' => {
|
||||
name: 'Name 1', email: 'mail@server.com',
|
||||
links: {
|
||||
profile: { name: 'N1', description: 'D1' }
|
||||
}
|
||||
}
|
||||
}, @user_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_embedding_ids_using_embed_namespace_and_embed_in_root_key
|
||||
@association.embed_in_root = true
|
||||
@association.embed_in_root_key = :linked
|
||||
@association.embed = :ids
|
||||
assert_equal({
|
||||
'user' => {
|
||||
name: 'Name 1', email: 'mail@server.com', 'profile_id' => @user.profile.object_id
|
||||
},
|
||||
linked: {
|
||||
'profiles' => [ { name: 'N1', description: 'D1' } ]
|
||||
}
|
||||
}, @user_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_associations_name_key_embedding_ids_serialization_using_serializable_hash
|
||||
@association = NameKeyUserSerializer._associations[:profile]
|
||||
@association.embed = :ids
|
||||
|
||||
assert_equal({
|
||||
name: 'Name 1', email: 'mail@server.com', 'profile' => @user.profile.object_id
|
||||
}, NameKeyUserSerializer.new(@user).serializable_hash)
|
||||
end
|
||||
|
||||
def test_associations_name_key_embedding_ids_serialization_using_as_json
|
||||
@association = NameKeyUserSerializer._associations[:profile]
|
||||
@association.embed = :ids
|
||||
|
||||
assert_equal({
|
||||
'name_key_user' => { name: 'Name 1', email: 'mail@server.com', 'profile' => @user.profile.object_id }
|
||||
}, NameKeyUserSerializer.new(@user).as_json)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,25 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class KeyFormatTest < Minitest::Test
|
||||
def test_lower_camel_format_option
|
||||
object = WebLog.new({ name: 'Name 1', display_name: 'Display Name 1'})
|
||||
serializer = WebLogSerializer.new(object, key_format: :lower_camel)
|
||||
|
||||
expected = { name: 'Name 1', displayName: 'Display Name 1' }
|
||||
|
||||
assert_equal expected, serializer.serializable_object
|
||||
end
|
||||
|
||||
def test_lower_camel_format_serializer
|
||||
object = WebLog.new({ name: 'Name 1', display_name: 'Display Name 1'})
|
||||
serializer = WebLogLowerCamelSerializer.new(object)
|
||||
|
||||
expected = { name: 'Name 1', displayName: 'Display Name 1' }
|
||||
|
||||
assert_equal expected, serializer.serializable_object
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,39 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class MetaTest < Minitest::Test
|
||||
def setup
|
||||
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
end
|
||||
|
||||
def test_meta
|
||||
profile_serializer = ProfileSerializer.new(@profile, root: 'profile', meta: { total: 10 })
|
||||
|
||||
assert_equal({
|
||||
'profile' => {
|
||||
name: 'Name 1',
|
||||
description: 'Description 1'
|
||||
},
|
||||
meta: {
|
||||
total: 10
|
||||
}
|
||||
}, profile_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_meta_using_meta_key
|
||||
profile_serializer = ProfileSerializer.new(@profile, root: 'profile', meta_key: :my_meta, my_meta: { total: 10 })
|
||||
|
||||
assert_equal({
|
||||
'profile' => {
|
||||
name: 'Name 1',
|
||||
description: 'Description 1'
|
||||
},
|
||||
my_meta: {
|
||||
total: 10
|
||||
}
|
||||
}, profile_serializer.as_json)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,42 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class OptionsTest < Minitest::Test
|
||||
def setup
|
||||
@serializer = ProfileSerializer.new(nil, context: {foo: :bar})
|
||||
end
|
||||
|
||||
def test_custom_options_are_accessible_from_serializer
|
||||
assert_equal({foo: :bar}, @serializer.context)
|
||||
end
|
||||
end
|
||||
|
||||
class SerializationOptionsTest < Minitest::Test
|
||||
def setup
|
||||
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
@profile_serializer = ProfileSerializer.new(@profile)
|
||||
@profile_serializer.instance_eval do
|
||||
def description
|
||||
serialization_options[:force_the_description]
|
||||
end
|
||||
end
|
||||
|
||||
@category = Category.new({name: 'Category 1'})
|
||||
@category_serializer = CategorySerializer.new(@category)
|
||||
end
|
||||
|
||||
def test_filtered_attributes_serialization
|
||||
forced_description = "This is a test"
|
||||
assert_equal({
|
||||
'profile' => { name: 'Name 1', description: forced_description }
|
||||
}, @profile_serializer.as_json(force_the_description: forced_description))
|
||||
end
|
||||
|
||||
def test_filtered_attributes_serialization_across_association
|
||||
assert_equal("'T1'",
|
||||
@category_serializer.as_json(highlight_keyword: 'T1')['category'][:posts][0][:title])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,117 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class RootAsOptionTest < Minitest::Test
|
||||
def setup
|
||||
@old_root = ProfileSerializer._root
|
||||
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
@serializer = ProfileSerializer.new(@profile, root: :initialize)
|
||||
ProfileSerializer._root = true
|
||||
end
|
||||
|
||||
def teardown
|
||||
ProfileSerializer._root = @old_root
|
||||
end
|
||||
|
||||
def test_root_is_not_displayed_using_serializable_hash
|
||||
assert_equal({
|
||||
name: 'Name 1', description: 'Description 1'
|
||||
}, @serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_root_using_as_json
|
||||
assert_equal({
|
||||
initialize: {
|
||||
name: 'Name 1', description: 'Description 1'
|
||||
}
|
||||
}, @serializer.as_json)
|
||||
end
|
||||
|
||||
def test_root_from_serializer_name
|
||||
@serializer = ProfileSerializer.new(@profile)
|
||||
|
||||
assert_equal({
|
||||
'profile' => {
|
||||
name: 'Name 1', description: 'Description 1'
|
||||
}
|
||||
}, @serializer.as_json)
|
||||
end
|
||||
|
||||
def test_root_as_argument_takes_precedence
|
||||
assert_equal({
|
||||
argument: {
|
||||
name: 'Name 1', description: 'Description 1'
|
||||
}
|
||||
}, @serializer.as_json(root: :argument))
|
||||
end
|
||||
|
||||
def test_using_false_root_in_initializer_takes_precedence
|
||||
ProfileSerializer._root = 'root'
|
||||
@serializer = ProfileSerializer.new(@profile, root: false)
|
||||
|
||||
assert_equal({
|
||||
name: 'Name 1', description: 'Description 1'
|
||||
}, @serializer.as_json)
|
||||
end
|
||||
|
||||
def test_root_inheritance
|
||||
ProfileSerializer._root = 'profile'
|
||||
|
||||
inherited_serializer_klass = Class.new(ProfileSerializer)
|
||||
inherited_serializer_klass._root = 'inherited_profile'
|
||||
|
||||
another_inherited_serializer_klass = Class.new(ProfileSerializer)
|
||||
|
||||
assert_equal('inherited_profile',
|
||||
inherited_serializer_klass._root)
|
||||
assert_equal('profile',
|
||||
another_inherited_serializer_klass._root)
|
||||
end
|
||||
end
|
||||
|
||||
class RootInSerializerTest < Minitest::Test
|
||||
def setup
|
||||
@old_root = ProfileSerializer._root
|
||||
ProfileSerializer._root = :in_serializer
|
||||
profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||
@serializer = ProfileSerializer.new(profile)
|
||||
@rooted_serializer = ProfileSerializer.new(profile, root: :initialize)
|
||||
end
|
||||
|
||||
def teardown
|
||||
ProfileSerializer._root = @old_root
|
||||
end
|
||||
|
||||
def test_root_is_not_displayed_using_serializable_hash
|
||||
assert_equal({
|
||||
name: 'Name 1', description: 'Description 1'
|
||||
}, @serializer.serializable_hash)
|
||||
end
|
||||
|
||||
def test_root_using_as_json
|
||||
assert_equal({
|
||||
in_serializer: {
|
||||
name: 'Name 1', description: 'Description 1'
|
||||
}
|
||||
}, @serializer.as_json)
|
||||
end
|
||||
|
||||
def test_root_in_initializer_takes_precedence
|
||||
assert_equal({
|
||||
initialize: {
|
||||
name: 'Name 1', description: 'Description 1'
|
||||
}
|
||||
}, @rooted_serializer.as_json)
|
||||
end
|
||||
|
||||
def test_root_as_argument_takes_precedence
|
||||
assert_equal({
|
||||
argument: {
|
||||
name: 'Name 1', description: 'Description 1'
|
||||
}
|
||||
}, @rooted_serializer.as_json(root: :argument))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,49 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class ScopeTest < Minitest::Test
|
||||
def setup
|
||||
@serializer = ProfileSerializer.new(nil, scope: current_user)
|
||||
end
|
||||
|
||||
def test_scope
|
||||
assert_equal('user', @serializer.scope)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_user
|
||||
'user'
|
||||
end
|
||||
end
|
||||
|
||||
class NestedScopeTest < Minitest::Test
|
||||
def setup
|
||||
@association = UserSerializer._associations[:profile]
|
||||
@old_association = @association.dup
|
||||
@user = User.new({ name: 'Name 1', email: 'mail@server.com', gender: 'M' })
|
||||
@user_serializer = UserSerializer.new(@user, scope: 'user')
|
||||
end
|
||||
|
||||
def teardown
|
||||
UserSerializer._associations[:profile] = @old_association
|
||||
end
|
||||
|
||||
def test_scope_passed_through
|
||||
@association.serializer_from_options = Class.new(Serializer) do
|
||||
def name
|
||||
scope
|
||||
end
|
||||
|
||||
attributes :name
|
||||
end
|
||||
|
||||
assert_equal({
|
||||
name: 'Name 1', email: 'mail@server.com', profile: { name: 'user' }
|
||||
}, @user_serializer.serializable_hash)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@ -1,35 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class UrlHelpersTest < Minitest::Test
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
def setup
|
||||
Object.const_set 'UserController', Class.new(ActionController::Base) do
|
||||
def show
|
||||
render text: 'profile'
|
||||
end
|
||||
end
|
||||
|
||||
Rails.application.routes.draw do
|
||||
get '/profile/:id', as: :profile, controller: :user, action: :show
|
||||
end
|
||||
end
|
||||
|
||||
def test_url_helpers_are_available
|
||||
serializer = Class.new(ActiveModel::Serializer) do
|
||||
attributes :url
|
||||
|
||||
def url
|
||||
profile_url(id: object.object_id)
|
||||
end
|
||||
end
|
||||
profile = Profile.new
|
||||
|
||||
assert_equal({ url: profile_url(id: profile.object_id) },
|
||||
serializer.new(profile).as_json)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,50 +0,0 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class SerializableTest
|
||||
class InstrumentationTest < Minitest::Test
|
||||
def setup
|
||||
@events = []
|
||||
|
||||
@subscriber = ActiveSupport::Notifications.subscribe('!serialize.active_model_serializers') do |name, start, finish, id, payload|
|
||||
@events << { name: name, serializer: payload[:serializer] }
|
||||
end
|
||||
end
|
||||
|
||||
def teardown
|
||||
ActiveSupport::Notifications.unsubscribe(@subscriber) if defined?(@subscriber)
|
||||
end
|
||||
|
||||
def test_instruments_default_serializer
|
||||
DefaultSerializer.new(1).as_json
|
||||
|
||||
assert_equal [{ name: '!serialize.active_model_serializers', serializer: 'ActiveModel::DefaultSerializer' }], @events
|
||||
end
|
||||
|
||||
def test_instruments_serializer
|
||||
profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
||||
serializer = ProfileSerializer.new(profile)
|
||||
|
||||
serializer.as_json
|
||||
|
||||
assert_equal [{ name: '!serialize.active_model_serializers', serializer: 'ProfileSerializer' }], @events
|
||||
end
|
||||
|
||||
def test_instruments_array_serializer
|
||||
profiles = [
|
||||
Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1'),
|
||||
Profile.new(name: 'Name 2', description: 'Description 2', comments: 'Comments 2')
|
||||
]
|
||||
serializer = ArraySerializer.new(profiles)
|
||||
|
||||
serializer.as_json
|
||||
|
||||
assert_equal [
|
||||
{ name: '!serialize.active_model_serializers', serializer: 'ProfileSerializer' },
|
||||
{ name: '!serialize.active_model_serializers', serializer: 'ProfileSerializer' },
|
||||
{ name: '!serialize.active_model_serializers', serializer: 'ActiveModel::ArraySerializer' }
|
||||
], @events
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user