Merge pull request #1371 from bf4/documentation_updates

[DOCS] Refactor, update, create documentation
This commit is contained in:
Benjamin Fleischer 2015-12-20 22:30:44 -06:00
commit fce856fc83
26 changed files with 750 additions and 487 deletions

View File

@ -7,12 +7,12 @@ Breaking changes:
- [#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 time i.e.
* 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
Adapter functions.
* named `Base` because it's a Rails-ism.
* It helps to isolate and highlight what the Adapter interface actually is.
Features:
@ -48,6 +48,7 @@ Misc:
- [#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 15:19 +00:00)
- [#1129](https://github.com/rails-api/active_model_serializers/pull/1129) Remove SerializableResource.serialize in favor of `.new` (@bf4)

View File

@ -8,6 +8,9 @@ http://www.commitstrip.com/en/2014/05/07/the-truth-behind-open-source-apps/](doc
## How can I help?
- [Filing an issue](CONTRIBUTING.md#filing-an-issue)
- [Writing code and comments](CONTRIBUTING#writing-code-and-comments)
### Filing an issue
Everyone is encouraged to open issues that are affecting them:
@ -20,7 +23,6 @@ bugs, ideas, documentation (`/docs`), performance problems everything helps!
- Check if your issue has already been reported.
- If you find an existing issue report, feel free to add further information to that report.
#### Writing
If possible, please include the following information when [reporting an
@ -82,22 +84,27 @@ And please don't forget to stay involved in the issue until it is closed! Thanks
- We are actively working to identify tasks under the label [**Good for New
Contributors**](https://github.com/rails-api/active_model_serializers/labels/Good%20for%20New%20Contributors).
Some bugs are expressly not good for new contributors, so don't expect 100% overlap between the two.
- [Changelog
Missing](https://github.com/rails-api/active_model_serializers/issues?q=label%3A%22Changelog+Missing%22+is%3Aclosed) is
an easy way to help out.
- If you want to work on new feature development, look for the label [**Feature**](https://github.com/rails-api/active_model_serializers/labels/Feature).
- [Fix a bug](https://github.com/rails-api/active_model_serializers/labels/Ready%20for%20PR).
- Ready for PR - A well defined bug, needs someone to PR a fix.
- Bug - Anything that is broken.
- Regression - A bug that did not exist in previous versions and isn't a new feature (applied in tandem with Bug).
- Performance - A performance related issue. We could track this as a bug, but usually these would have slightly lower priority than standard bugs.
- [Develop new features](https://github.com/rails-api/active_model_serializers/labels/Feature).
- [Improve code quality](https://codeclimate.com/github/rails-api/active_model_serializers/code?sort=smell_count&sort_direction=desc).
- [Improve amount of code exercised by tests](https://codeclimate.com/github/rails-api/active_model_serializers/coverage?sort=covered_percent&sort_direction=asc).
- We are also encouraging comments to substantial changes (larger than bugfixes and simple features) under an
"RFC" (Request for Comments) process before we start active development.
Look for the [**RFC**](https://github.com/rails-api/active_model_serializers/labels/RFC) label.
## Issue Labeling
ActiveModelSerializers uses a subset of [StandardIssueLabels](https://github.com/wagenet/StandardIssueLabels) for Github Issues. You can [see our labels here](https://github.com/rails-api/active_model_serializers/labels).
## Submitting a pull request (PR)
#### Submitting a pull request (PR)
1. The vast majority of development is happening under the `master` branch.
This is where we would suggest you start.
@ -147,13 +154,13 @@ Remember to [squash your commits](CONTRIBUTING.md#about-pull-requests-prs) and r
- by force pushing to it
- A maintainer can make any changes themselves and manually merge the code in.
### Commit Messages
#### Commit Messages
- [A Note About Git Commit Messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
- [http://stopwritingramblingcommitmessages.com/](http://stopwritingramblingcommitmessages.com/)
- [ThoughtBot style guide](https://github.com/thoughtbot/guides/tree/master/style#git)
### About Pull Requests (PR's)
#### About Pull Requests (PR's)
- [Using Pull Requests](https://help.github.com/articles/using-pull-requests)
- [Github pull requests made easy](http://www.element84.com/github-pull-requests-made-easy.html)
@ -161,9 +168,34 @@ Remember to [squash your commits](CONTRIBUTING.md#about-pull-requests-prs) and r
- [Level up your Git](http://rakeroutes.com/blog/deliberate-git/)
- [All Your Open Source Code Are Belong To Us](http://www.benjaminfleischer.com/2013/07/30/all-your-open-source-code-are-belong-to-us/)
### Running tests
## Issue Labeling
#### Running with Rake
ActiveModelSerializers uses a subset of [StandardIssueLabels](https://github.com/wagenet/StandardIssueLabels) for Github Issues. You can [see our labels here](https://github.com/rails-api/active_model_serializers/labels).
## Running tests
Run tests against different Rails versions by setting the RAILS_VERSION variable
and bundling gems. To test against all versions, you can do something like:
```bash
for version in 4.0 4.1 4.2 master; 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"
fi
unset RAILS_VERSION
done
```
### Running with Rake
The easiest way to run the unit tests is through Rake. The default task runs
the entire test suite for all classes. For more information, checkout the

453
README.md
View File

@ -1,247 +1,58 @@
# ActiveModelSerializers
[![Build Status](https://travis-ci.org/rails-api/active_model_serializers.svg?branch=master)](https://travis-ci.org/rails-api/active_model_serializers)
<a href="https://codeclimate.com/github/rails-api/active_model_serializers"><img src="https://codeclimate.com/github/rails-api/active_model_serializers/badges/gpa.svg" /></a>
<a href="https://codeclimate.com/github/rails-api/active_model_serializers/coverage"><img src="https://codeclimate.com/github/rails-api/active_model_serializers/badges/coverage.svg" /></a>
(Windows: [![Build status](https://ci.appveyor.com/api/projects/status/x6xdjydutm54gvyt/branch/master?svg=true)](https://ci.appveyor.com/project/joaomdmoura/active-model-serializers/branch/master))
[![Code Quality](https://codeclimate.com/github/rails-api/active_model_serializers/badges/gpa.svg)](https://codeclimate.com/github/rails-api/active_model_serializers)
[![Test Coverage](https://codeclimate.com/github/rails-api/active_model_serializers/badges/coverage.svg)](https://codeclimate.com/github/rails-api/active_model_serializers/coverage)
_Windows Build Status -_ [![Build status](https://ci.appveyor.com/api/projects/status/x6xdjydutm54gvyt/branch/master?svg=true)](https://ci.appveyor.com/project/joaomdmoura/active-model-serializers/branch/master)
## Documentation
- [0.10 (master) Documentation](https://github.com/rails-api/active_model_serializers/tree/master)
- [![API Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/github/rails-api/active_model_serializers)
- [Guides](docs)
- [0.9 (0-9-stable) Documentation](https://github.com/rails-api/active_model_serializers/tree/0-9-stable)
- [0.8 (0-8-stable) Documentation](https://github.com/rails-api/active_model_serializers/tree/0-8-stable)
## About
ActiveModelSerializers brings convention over configuration to your JSON generation.
AMS does this through two components: **serializers** and **adapters**.
ActiveModelSerializers works through two components: **serializers** and **adapters**.
Serializers describe _which_ attributes and relationships should be serialized.
Adapters describe _how_ attributes and relationships should be serialized.
By default AMS will use the **Attributes Adapter**. But we strongly advise you to use **JsonApi Adapter** that follows 1.0 of the format specified in [jsonapi.org/format](http://jsonapi.org/format).
Check how to change the adapter in the sections bellow.
SerializableResource co-ordinates the resource, Adapter and Serializer to produce the
resource serialization. The serialization has the `#as_json`, `#to_json` and `#serializable_hash`
methods used by the Rails JSON Renderer. (SerializableResource actually delegates
these methods to the adapter.)
# Documentation
By default ActiveModelSerializers will use the **Attributes Adapter**.
But we strongly advise you to use **JsonApi Adapter**, which
follows 1.0 of the format specified in [jsonapi.org/format](http://jsonapi.org/format).
Check how to change the adapter in the sections below.
Master
## RELEASE CANDIDATE, PLEASE READ
- [![API Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/github/rails-api/active_model_serializers)
- [Guides](https://github.com/rails-api/active_model_serializers/tree/master/docs)
This is the **master** branch of ActiveModelSerializers.
# RELEASE CANDIDATE, PLEASE READ
It will become the `0.10.0` release when it's ready. Currently this is a release candidate.
This is the master branch of AMS. It will become the `0.10.0` release when it's
ready. Currently this is a release candidate. This is **not** backward
compatible with `0.9.0` or `0.8.0`.
`0.10.x` is **not** backward compatible with `0.9.x` nor `0.8.x`.
`0.10.x` will be based on the `0.8.0` code, but with a more flexible
architecture. We'd love your help. [Learn how you can help here.](https://github.com/rails-api/active_model_serializers/blob/master/CONTRIBUTING.md)
architecture. We'd love your help. [Learn how you can help here.](CONTRIBUTING.md)
## Example
It is generally safe and recommended to use the master branch.
Given two models, a `Post(title: string, body: text)` and a
`Comment(name: string, body: text, post_id: integer)`, you will have two
serializers:
```ruby
class PostSerializer < ActiveModel::Serializer
cache key: 'posts', expires_in: 3.hours
attributes :title, :body
has_many :comments
end
```
and
```ruby
class CommentSerializer < ActiveModel::Serializer
attributes :name, :body
belongs_to :post
end
```
Generally speaking, you as a user of AMS will write (or generate) these
serializer classes. If you want to use a different adapter, such as a JsonApi, you can
change this in an initializer:
```ruby
ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::JsonApi
```
or
```ruby
ActiveModel::Serializer.config.adapter = :json_api
```
You won't need to implement an adapter unless you wish to use a new format or
media type with AMS.
If you want to have a root key on your responses you should use the Json adapter, instead of the default Attributes:
```ruby
ActiveModel::Serializer.config.adapter = :json
```
If you would like the key in the outputted JSON to be different from its name in ActiveRecord, you can use the :key option to customize it:
```ruby
class PostSerializer < ActiveModel::Serializer
attributes :id, :body
# look up :subject on the model, but use +title+ in the JSON
attribute :subject, :key => :title
has_many :comments
end
```
In your controllers, when you use `render :json`, Rails will now first search
for a serializer for the object and use it if available.
```ruby
class PostsController < ApplicationController
def show
@post = Post.find(params[:id])
render json: @post
end
end
```
In this case, Rails will look for a serializer named `PostSerializer`, and if
it exists, use it to serialize the `Post`.
### Specify a serializer
If you wish to use a serializer other than the default, you can explicitly pass it to the renderer.
#### 1. For a resource:
```ruby
render json: @post, serializer: PostPreviewSerializer
```
#### 2. For an array resource:
```ruby
# Use the default `CollectionSerializer`, which will use `each_serializer` to
# serialize each element
render json: @posts, each_serializer: PostPreviewSerializer
# Or, you can explicitly provide the collection serializer as well
render json: @posts, serializer: CollectionSerializer, each_serializer: PostPreviewSerializer
```
### Meta
If you want a `meta` attribute in your response, specify it in the `render`
call:
```ruby
render json: @post, meta: { total: 10 }
```
The key can be customized using `meta_key` option.
```ruby
render json: @post, meta: { total: 10 }, meta_key: "custom_meta"
```
`meta` will only be included in your response if you are using an Adapter that supports `root`,
as JsonAPI and Json adapters, the default adapter (Attributes) doesn't have `root`.
### Using a serializer without `render`
At times, you might want to use a serializer without rendering it to the view. For those cases, you can create an instance of `ActiveModel::SerializableResource` with
the resource you want to be serialized and call `.serializable_hash`.
```ruby
def create
@message = current_user.messages.create!(message_params)
MessageCreationWorker.perform(serialized_message)
head 204
end
def serialized_message
ActiveModel::SerializableResource.new(@message).serializable_hash
end
```
### Overriding association methods
If you want to override any association, you can use:
```ruby
class PostSerializer < ActiveModel::Serializer
attributes :id, :body
has_many :comments
def comments
object.comments.active
end
end
```
### Overriding attribute methods
If you want to override any attribute, you can use:
```ruby
class PostSerializer < ActiveModel::Serializer
attributes :id, :body
has_many :comments
def body
object.body.downcase
end
end
```
### Built in Adapters
#### Attributes
It's the default adapter, it generates a json response without a root key.
Doesn't follow any specific convention.
#### JSON
It also generates a json response but always with a root key. The root key **can't be overridden**, and will be automatically defined accordingly with the objects being serialized.
Doesn't follow any specific convention.
#### JSON API
This adapter follows 1.0 of the format specified in
[jsonapi.org/format](http://jsonapi.org/format). It will include the associated
resources in the `"included"` member when the resource names are included in the
`include` option. Including nested associated resources is also supported.
```ruby
render @posts, include: ['author', 'comments', 'comments.author']
# or
render @posts, include: 'author,comments,comments.author'
```
In addition, two types of wildcards may be used. `*` includes one level of associations, and `**` includes all recursively. These can be combined with other paths.
```ruby
render @posts, include: '**' # or '*' for a single layer
```
The following would render posts and include the author, the author's comments, and every resource referenced by the author's comments (recursively). It could be combined, like above, with other paths in any combination desired.
```ruby
render @posts, include: 'author.comments.**'
```
The JSON API [specifies](http://jsonapi.org/format/#fetching-includes) that the user may supply a parameter specifying which related resources are to be included:
```ruby
render @posts, include: params[:include]
```
This raises some security concerns since the user could pass in `include=**`, so filter the values for `include` appropriately if you decide to support this JSON API feature.
For more information, see the post '[The future of
AMS](https://medium.com/@joaomdmoura/the-future-of-ams-e5f9047ca7e9)'.
## Installation
Note: *ActiveModelSerializers is already included on Rails >= 5*
Add this line to your application's Gemfile:
```
@ -254,145 +65,83 @@ And then execute:
$ bundle
```
## Creating a Serializer
## Getting Started
The easiest way to create a new serializer is to generate a new resource, which
will generate a serializer at the same time:
See [Getting Started](docs/general/getting_started.md) for the nuts and bolts.
```
$ rails g resource post title:string body:string
```
This will generate a serializer in `app/serializers/post_serializer.rb` for
your new model. You can also generate a serializer for an existing model with
the serializer generator:
```
$ rails g serializer post
```
The generated serializer will contain basic `attributes` and
`has_many`/`has_one`/`belongs_to` declarations, based on the model. For example:
```ruby
class PostSerializer < ActiveModel::Serializer
attributes :title, :body
has_many :comments
has_one :author
end
```
and
```ruby
class CommentSerializer < ActiveModel::Serializer
attributes :name, :body
belongs_to :post_id
end
```
The attribute names are a **whitelist** of attributes to be serialized.
The `has_many`, `has_one`, and `belongs_to` declarations describe relationships between
resources. By default, when you serialize a `Post`, you will get its `Comments`
as well.
You may also use the `:serializer` option to specify a custom serializer class, for example:
```ruby
has_many :comments, serializer: CommentPreviewSerializer
```
And you can change the JSON key that the serializer should use for a particular association:
```ruby
has_many :comments, key: :reviews
```
## Pagination
Pagination links will be included in your response automatically as long
as the resource is paginated using [Kaminari](https://github.com/amatsuda/kaminari) or
[WillPaginate](https://github.com/mislav/will_paginate) and
if you are using the ```JsonApi``` adapter.
Although the others adapters does not have this feature, it is possible to
implement pagination links to `JSON` adapter. For more information about it,
please see in our docs [How to add pagination
links](https://github.com/rails-api/active_model_serializers/blob/master/docs/howto/add_pagination_links.md).
## Caching
To cache a serializer, call ```cache``` and pass its options.
The options are the same options of ```ActiveSupport::Cache::Store```, plus
a ```key``` option that will be the prefix of the object cache
on a pattern ```"#{key}/#{object.id}-#{object.updated_at}"```.
The cache support is optimized to use the cached object in multiple request. An object cached on a ```show``` request will be reused at the ```index```. If there is a relationship with another cached serializer it will also be created and reused automatically.
**[NOTE] Every object is individually cached.**
**[NOTE] The cache is automatically expired after an object is updated, but it's not deleted.**
```ruby
cache(options = nil) # options: ```{key, expires_in, compress, force, race_condition_ttl}```
```
Take the example bellow:
```ruby
class PostSerializer < ActiveModel::Serializer
cache key: 'post', expires_in: 3.hours
attributes :title, :body
has_many :comments
end
```
On this example every ```Post``` object will be cached with
the key ```"post/#{post.id}-#{post.updated_at}"```. You can use this key to expire it as you want,
but in this case it will be automatically expired after 3 hours.
### Fragment Caching
If there is some API endpoint that shouldn't be fully cached, you can still optimise it, using Fragment Cache on the attributes and relationships that you want to cache.
You can define the attribute by using ```only``` or ```except``` option on cache method.
**[NOTE] Cache serializers will be used at their relationships**
Example:
```ruby
class PostSerializer < ActiveModel::Serializer
cache key: 'post', expires_in: 3.hours, only: [:title]
attributes :title, :body
has_many :comments
end
```
## Serializing non-ActiveRecord objects
All serializable resources must pass the ActiveModel::Serializer::Lint::Tests.
See the ActiveModelSerializers::Model for a base class that implements the full
API for a plain-old Ruby object (PORO).
## Hooks
To run a hook when ActiveModelSerializers is loaded, use `ActiveSupport.on_load(:active_model_serializers) do end`
More information is available in the [Guides](docs) and
[High-level behavior](README.md#high-level-behavior).
## Getting Help
If you find a bug, please report an [Issue](https://github.com/rails-api/active_model_serializers/issues/new).
If you find a bug, please report an [Issue](https://github.com/rails-api/active_model_serializers/issues/new)
and see our [contributing guide](CONTRIBUTING.md).
If you have a question, please [post to Stack Overflow](http://stackoverflow.com/questions/tagged/active-model-serializers).
If you'd like to chat, we have a [community slack](http://amserializers.herokuapp.com).
Thanks!
## High-level behavior
Given a [serializable model](lib/active_model/serializer/lint.rb):
```ruby
# either
class SomeResource < ActiveRecord::Base
# columns: title, body
end
# or
class SomeResource < ActiveModelSerializers::Model
attr_accessor :title, :body
end
```
And initialized as:
```ruby
resource = SomeResource.new(title: 'ActiveModelSerializers', body: 'Convention over configuration')
```
Given a serializer for the serializable model:
```ruby
class SomeSerializer < ActiveModel::Serializer
attribute :title, key: :name
attributes :body
end
```
The model can be serialized as:
```ruby
options = {}
serialization = SerializableResource.new(resource, options)
serialization.to_json
serialization.as_json
```
SerializableResource delegates to the adapter, which it builds as:
```ruby
adapter_options = {}
adapter = Adapter.create(serializer, adapter_options)
adapter.to_json
adapter.as_json
adapter.serializable_hash
```
The adapter formats the serializer's attributes and associations (a.k.a. includes):
```ruby
serializer_options = {}
serializer = SomeSerializer.new(resource, serializer_options)
serializer.attributes
serializer.associations
```
See [ARCHITECTURE.md](docs/ARCHITECTURE.md) for more information.
# Contributing
See [CONTRIBUTING.md](https://github.com/rails-api/active_model_serializers/blob/master/CONTRIBUTING.md)
See [CONTRIBUTING.md](CONTRIBUTING.md)

View File

@ -43,7 +43,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'activerecord', rails_versions
# arel
# activesuport
# activesupport
# activemodel
# Soft dependency for pagination

View File

@ -1,3 +1,5 @@
[Back to Guides](README.md)
# ARCHITECTURE
An **`ActiveModel::Serializer`** wraps a [serializable resource](https://github.com/rails/rails/blob/4-2-stable/activemodel/lib/active_model/serialization.rb)

View File

@ -1,40 +1,34 @@
# Docs - ActiveModel::Serializer 0.10.x
This is the documentation of AMS, it's focused on the **0.10.x version.**
This is the documentation of ActiveModelSerializers, it's focused on the **0.10.x version.**
-----
## General
- [Getting Started](general/getting_started.md)
- [Adapters](general/adapters.md)
- [Configuration Options](general/configuration_options.md)
- [Serializers](general/serializers.md)
- [Adapters](general/adapters.md)
- [Rendering](general/rendering.md)
- [Caching](general/caching.md)
- [Logging](general/logging.md)
- [Instrumentation](general/instrumentation.md)
- [JSON API Schema](jsonapi/schema.md)
- [ARCHITECTURE](ARCHITECTURE.md)
## How to
- [How to add root key](howto/add_root_key.md)
- [How to add pagination links](howto/add_pagination_links.md)
- [Using AMS Outside Of Controllers](howto/outside_controller_use.md)
- [Using ActiveModelSerializers Outside Of Controllers](howto/outside_controller_use.md)
## Integrations
| Integration | Supported AMS versions | Gem name and/or link
| Integration | Supported ActiveModelSerializers versions | Gem name and/or link
|----|-----|----
| Ember.js | 0.9.x | [active-model-adapter](https://github.com/ember-data/active-model-adapter)
| Ember.js | 0.10.x + | [docs/integrations/ember-and-json-api.md](integrations/ember-and-json-api.md)
| Grape | 0.10.x + | [docs/integrations/grape.md](integrations/grape.md) |
| Grape | 0.9.x | https://github.com/jrhe/grape-active_model_serializers/ |
| Sinatra | 0.9.x | https://github.com/SauloSilva/sinatra-active-model-serializers/
## Getting Help
If you find a bug, please report an [Issue](https://github.com/rails-api/active_model_serializers/issues/new).
If you have a question, please [post to Stack Overflow](http://stackoverflow.com/questions/tagged/active-model-serializers).
Thanks!
## Contributing
See [CONTRIBUTING.md](https://github.com/rails-api/active_model_serializers/blob/master/CONTRIBUTING.md)

View File

@ -1,9 +1,40 @@
[Back to Guides](../README.md)
# Adapters
AMS works through two components: **serializers** and **adapters**.
Serializers describe _which_ attributes and relationships should be serialized.
Adapters describe _how_ attributes and relationships should be serialized.
You can use one of the built-in adapters (```Attributes``` is the default one) or create one by yourself, but you won't need to implement an adapter unless you wish to use a new format or media type with AMS.
ActiveModelSerializers offers the ability to configure which adapter
to use both globally and/or when serializing (usually when rendering).
The global adapter configuration is set on [`ActiveModelSerializers.config`](configuration_options.md).
It should be set only once, preferably at initialization.
For example:
```ruby
ActiveModelSerializers.config.adapter = ActiveModel::Serializer::Adapter::JsonApi
```
or
```ruby
ActiveModelSerializers.config.adapter = :json_api
```
or
```ruby
ActiveModelSerializers.config.adapter = :json
```
The local adapter option is in the format `adapter: adapter`, where `adapter` is
any of the same values as set globally.
The configured adapter can be set as a symbol, class, or class name, as described in
[Advanced adapter configuration](adapters.md#advanced-adapter-configuration).
The `Attributes` adapter does not include a root key. It is just the serialized attributes.
Use either the `JSON` or `JSON API` adapters if you want the response document to have a root key.
## Built in Adapters
@ -14,48 +45,69 @@ Doesn't follow any specific convention.
### JSON
It also generates a json response but always with a root key. The root key **can't be overridden**, and will be automatically defined accordingly to the objects being serialized.
The response document always with a root key.
The root key **can't be overridden**, and will be derived from the resource being serialized.
Doesn't follow any specific convention.
### JSON API
This adapter follows **version 1.0** of the format specified in
[jsonapi.org/format](http://jsonapi.org/format). It will include the associated
resources in the `"included"` member when the resource names are included in the
`include` option.
This adapter follows **version 1.0** of the [format specified](../jsonapi/schema.md) in
[jsonapi.org/format](http://jsonapi.org/format).
#### Included
It will include the associated resources in the `"included"` member
when the resource names are included in the `include` option.
Including nested associated resources is also supported.
```ruby
render @posts, include: ['authors', 'comments']
render json: @posts, include: ['author', 'comments', 'comments.author']
# or
render json: @posts, include: 'author,comments,comments.author'
```
or
In addition, two types of wildcards may be used:
- `*` includes one level of associations.
- `**` includes all recursively.
These can be combined with other paths.
```ruby
render @posts, include: 'authors,comments'
render json: @posts, include: '**' # or '*' for a single layer
```
The format of the `include` option can be either a String composed of a comma-separated list of [relationship paths](http://jsonapi.org/format/#fetching-includes), an Array of Symbols and Hashes, or a mix of both.
The format of the `include` option can be either:
## Choosing an adapter
- a String composed of a comma-separated list of [relationship paths](http://jsonapi.org/format/#fetching-includes).
- an Array of Symbols and Hashes.
- a mix of both.
If you want to use a specify a default adapter, such as JsonApi, you can change this in an initializer:
The following would render posts and include:
- the author
- the author's comments, and
- every resource referenced by the author's comments (recursively).
It could be combined, like above, with other paths in any combination desired.
```ruby
ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::JsonApi
render json: @posts, include: 'author.comments.**'
```
or
##### Security Considerations
Since the included options may come from the query params (i.e. user-controller):
```ruby
ActiveModel::Serializer.config.adapter = :json_api
render json: @posts, include: params[:include]
```
If you want to have a root key for each resource in your responses, you should use the Json or
JsonApi adapters instead of the default Attributes:
The user could pass in `include=**`.
```ruby
ActiveModel::Serializer.config.adapter = :json
```
We recommend filtering any user-supplied includes appropriately.
## Advanced adapter configuration

52
docs/general/caching.md Normal file
View File

@ -0,0 +1,52 @@
[Back to Guides](../README.md)
# Caching
To cache a serializer, call ```cache``` and pass its options.
The options are the same options of ```ActiveSupport::Cache::Store```, plus
a ```key``` option that will be the prefix of the object cache
on a pattern ```"#{key}/#{object.id}-#{object.updated_at}"```.
The cache support is optimized to use the cached object in multiple request. An object cached on a ```show``` request will be reused at the ```index```. If there is a relationship with another cached serializer it will also be created and reused automatically.
**[NOTE] Every object is individually cached.**
**[NOTE] The cache is automatically expired after an object is updated, but it's not deleted.**
```ruby
cache(options = nil) # options: ```{key, expires_in, compress, force, race_condition_ttl}```
```
Take the example bellow:
```ruby
class PostSerializer < ActiveModel::Serializer
cache key: 'post', expires_in: 3.hours
attributes :title, :body
has_many :comments
end
```
On this example every ```Post``` object will be cached with
the key ```"post/#{post.id}-#{post.updated_at}"```. You can use this key to expire it as you want,
but in this case it will be automatically expired after 3 hours.
## Fragment Caching
If there is some API endpoint that shouldn't be fully cached, you can still optimise it, using Fragment Cache on the attributes and relationships that you want to cache.
You can define the attribute by using ```only``` or ```except``` option on cache method.
**[NOTE] Cache serializers will be used at their relationships**
Example:
```ruby
class PostSerializer < ActiveModel::Serializer
cache key: 'post', expires_in: 3.hours, only: [:title]
attributes :title, :body
has_many :comments
end
```

View File

@ -1,6 +1,9 @@
[Back to Guides](../README.md)
# Configuration Options
The following configuration options can be set on `ActiveModel::Serializer.config` inside an initializer.
The following configuration options can be set on `ActiveModelSerializers.config`,
preferably inside an initializer.
## General
@ -18,3 +21,7 @@ The following configuration options can be set on `ActiveModel::Serializer.confi
Default: `'1.0'`.
- `jsonapi_toplevel_meta`: Optional metadata. Not included if empty.
Default: `{}`.
## Hooks
To run a hook when ActiveModelSerializers is loaded, use `ActiveSupport.on_load(:active_model_serializers) do end`

View File

@ -1,21 +1,7 @@
[Back to Guides](../README.md)
# Getting Started
## Installation
### ActiveModel::Serializer is already included on Rails >= 5
Add this line to your application's Gemfile:
```
gem 'active_model_serializers'
```
And then execute:
```
$ bundle
```
## Creating a Serializer
The easiest way to create a new serializer is to generate a new resource, which
@ -33,7 +19,7 @@ the serializer generator:
$ rails g serializer post
```
The generated seralizer will contain basic `attributes` and
The generated serializer will contain basic `attributes` and
`has_many`/`has_one`/`belongs_to` declarations, based on the model. For example:
```ruby
@ -42,7 +28,6 @@ class PostSerializer < ActiveModel::Serializer
has_many :comments
has_one :author
end
```
@ -53,13 +38,20 @@ class CommentSerializer < ActiveModel::Serializer
attributes :name, :body
belongs_to :post_id
end
```
The attribute names are a **whitelist** of attributes to be serialized.
The `has_many`, `has_one`, and `belongs_to` declarations describe relationships between
resources. By default, when you serialize a `Post`, you will get its `Comments`
as well.
For more information, see [Serializers](docs/general/serializers.md).
### Namespaced Models
When serializing a model inside a namespace, such as `Api::V1::Post`, AMS will expect the corresponding serializer to be inside the same namespace (namely `Api::V1::PostSerializer`).
When serializing a model inside a namespace, such as `Api::V1::Post`, ActiveModelSerializers will expect the corresponding serializer to be inside the same namespace (namely `Api::V1::PostSerializer`).
### Model Associations and Nested Serializers
@ -69,7 +61,7 @@ class PostSerializer < ActiveModel::Serializer
has_many :comments
end
```
AMS will look for `PostSerializer::CommentSerializer` in priority, and fall back to `::CommentSerializer` in case the former does not exist. This allows for more control over the way a model gets serialized as an association of an other model.
ActiveModelSerializers will look for `PostSerializer::CommentSerializer` in priority, and fall back to `::CommentSerializer` in case the former does not exist. This allows for more control over the way a model gets serialized as an association of an other model.
For example, in the following situation:
@ -86,11 +78,13 @@ class PostSerializer < ActiveModel::Serializer
end
```
AMS will use `PostSerializer::CommentSerializer` (thus including only the `:body_short` attribute) when serializing a `Comment` as part of a `Post`, but use `::CommentSerializer` when serializing a `Comment` directly (thus including `:body, :date, :nb_likes`).
ActiveModelSerializers will use `PostSerializer::CommentSerializer` (thus including only the `:body_short` attribute) when serializing a `Comment` as part of a `Post`, but use `::CommentSerializer` when serializing a `Comment` directly (thus including `:body, :date, :nb_likes`).
## Rails Integration
AMS will automatically integrate with you Rails app, you won't need to update your controller, this is a example of how it will look like:
ActiveModelSerializers will automatically integrate with your Rails app,
so you won't need to update your controller.
This is a example of how the controller will look:
```ruby
class PostsController < ApplicationController

View File

@ -1,3 +1,5 @@
[Back to Guides](../README.md)
# Instrumentation
ActiveModelSerializers uses the
@ -30,6 +32,7 @@ ActiveSupport::Notifications.subscribe 'render.active_model_serializers' do |*ar
# event.payload
# whatever
end
```
## [LogSubscriber](http://api.rubyonrails.org/classes/ActiveSupport/LogSubscriber.html)

View File

@ -1,11 +1,13 @@
[Back to Guides](../README.md)
# Logging
If we are using ActiveModel::Serializers on Rails app by default the `Rails.logger` will be used.
The default logger in a Rails application will be `Rails.logger`.
On a non Rails enviroment by default the `ActiveSupport::TaggedLogging` will be
used.
When there is no `Rails.logger`, the default logger is an instance of
`ActiveSupport::TaggedLogging` logging to STDOUT.
If we need to customize the logger we can define this in an initializer:
You may customize the logger in an initializer, for example:
```ruby
ActiveModelSerializers.logger = Logger.new(STDOUT)

136
docs/general/rendering.md Normal file
View File

@ -0,0 +1,136 @@
[Back to Guides](../README.md)
# Rendering
### Implicit Serializer
In your controllers, when you use `render :json`, Rails will now first search
for a serializer for the object and use it if available.
```ruby
class PostsController < ApplicationController
def show
@post = Post.find(params[:id])
render json: @post
end
end
```
In this case, Rails will look for a serializer named `PostSerializer`, and if
it exists, use it to serialize the `Post`.
### Explicit Serializer
If you wish to use a serializer other than the default, you can explicitly pass it to the renderer.
#### 1. For a resource:
```ruby
render json: @post, serializer: PostPreviewSerializer
```
#### 2. For a resource collection:
Specify the serializer for each resource with `each_serializer`
```ruby
render json: @posts, each_serializer: PostPreviewSerializer
```
The default serializer for collections is `CollectionSerializer`.
Specify the collection serializer with the `serializer` option.
```ruby
render json: @posts, serializer: CollectionSerializer, each_serializer: PostPreviewSerializer
```
## Serializing non-ActiveRecord objects
All serializable resources must pass the
[ActiveModel::Serializer::Lint::Tests](../../lib/active_model/serializer/lint.rb#L17).
See the ActiveModelSerializers::Model for a base class that implements the full
API for a plain-old Ruby object (PORO).
## SerializableResource options
The `options` hash passed to `render` or `ActiveModel::SerializableResource.new(resource, options)`
are partitioned into `serializer_opts` and `adapter_opts`. `adapter_opts` are passed to new Adapters;
`serializer_opts` are passed to new Serializers.
The `adapter_opts` are specified in [ActiveModel::SerializableResource::ADAPTER_OPTIONS](../../lib/active_model/serializable_resource.rb#L4).
The `serializer_opts` are the remaining options.
(In Rails, the `options` are also passed to the `as_json(options)` or `to_json(options)`
methods on the resource serialization by the Rails JSON renderer. They are, therefore, important
to know about, but not part of ActiveModelSerializers.)
See [ARCHITECTURE](../ARCHITECTURE.md) for more information.
### adapter_opts
#### fields
PR please :)
#### adapter
PR please :)
#### meta
If you want a `meta` attribute in your response, specify it in the `render`
call:
```ruby
render json: @post, meta: { total: 10 }
```
The key can be customized using `meta_key` option.
```ruby
render json: @post, meta: { total: 10 }, meta_key: "custom_meta"
```
`meta` will only be included in your response if you are using an Adapter that supports `root`,
as JsonAPI and Json adapters, the default adapter (Attributes) doesn't have `root`.
#### meta_key
PR please :)
#### links
PR please :)
### serializer_opts
#### include
PR please :)
#### root
PR please :)
#### serializer
PR please :)
#### scope
PR please :)
#### scope_name
PR please :)
## Using a serializer without `render`
See [Usage outside of a controller](../howto/outside_controller_use.md#serializing-before-controller-render).
## Pagination
See [How to add pagination links](https://github.com/rails-api/active_model_serializers/blob/master/docs/howto/add_pagination_links.md).

213
docs/general/serializers.md Normal file
View File

@ -0,0 +1,213 @@
[Back to Guides](../README.md)
# Serializers
Given a serializer class:
```ruby
class SomeSerializer < ActiveModel::Serializer
end
```
The following methods may be defined in it:
### Attributes
#### ::attributes
Serialization of the resource `title` and `body`
| In Serializer | #attributes |
|---------------------------- |-------------|
| `attributes :title, :body` | `{ title: 'Some Title', body: 'Some Body' }`
| `attributes :title, :body`<br>`def body "Special #{object.body}" end` | `{ title: 'Some Title', body: 'Special Some Body' }`
#### ::attribute
Serialization of the resource `title`
| In Serializer | #attributes |
|---------------------------- |-------------|
| `attribute :title` | `{ title: 'Some Title' } `
| `attribute :title, key: :name` | `{ name: 'Some Title' } `
| `attribute :title { 'A Different Title'}` | `{ title: 'A Different Title' } `
| `attribute :title`<br>`def title 'A Different Title' end` | `{ title: 'A Different Title' }`
### Associations
#### ::has_one
e.g.
```ruby
has_one :bio
has_one :blog, key: :site
has_one :maker, virtual_value: { id: 1 }
```
#### ::has_many
e.g.
```ruby
has_many :comments
has_many :comments, key: :reviews
has_many :comments, serializer: CommentPreviewSerializer
has_many :reviews, virtual_value: [{ id: 1 }, { id: 2 }]
has_many :comments, key: :last_comments do
last(1)
end
```
#### ::belongs_to
e.g.
```ruby
belongs_to :author, serializer: AuthorPreviewSerializer
belongs_to :author, key: :writer
belongs_to :post
belongs_to :blog
def blog
Blog.new(id: 999, name: 'Custom blog')
end
```
### Caching
#### ::cache
e.g.
```ruby
cache key: 'post', expires_in: 0.1, skip_digest: true
cache expires_in: 1.day, skip_digest: true
cache key: 'writer', skip_digest: true
cache only: [:name], skip_digest: true
cache except: [:content], skip_digest: true
cache key: 'blog'
cache only: [:id]
```
#### #cache_key
e.g.
```ruby
# Uses a custom non-time-based cache key
def cache_key
"#{self.class.name.downcase}/#{self.id}"
end
```
### Other
#### ::type
e.g.
```ruby
class UserProfileSerializer < ActiveModel::Serializer
type 'profile'
end
```
#### ::link
e.g.
```ruby
link :other, 'https://example.com/resource'
link :self do
href "https://example.com/link_author/#{object.id}"
end
```
#### #object
The object being serialized.
#### #root
PR please :)
#### #scope
PR please :)
#### #read_attribute_for_serialization(key)
The serialized value for a given key. e.g. `read_attribute_for_serialization(:title) #=> 'Hello World'`
#### #links
PR please :)
#### #json_key
PR please :)
## Examples
Given two models, a `Post(title: string, body: text)` and a
`Comment(name: string, body: text, post_id: integer)`, you will have two
serializers:
```ruby
class PostSerializer < ActiveModel::Serializer
cache key: 'posts', expires_in: 3.hours
attributes :title, :body
has_many :comments
end
```
and
```ruby
class CommentSerializer < ActiveModel::Serializer
attributes :name, :body
belongs_to :post
end
```
Generally speaking, you, as a user of ActiveModelSerializers, will write (or generate) these
serializer classes.
## More Info
For more information, see [the Serializer class on GitHub](https://github.com/rails-api/active_model_serializers/blob/master/lib/active_model/serializer.rb)
## Overriding association methods
If you want to override any association, you can use:
```ruby
class PostSerializer < ActiveModel::Serializer
attributes :id, :body
has_many :comments
def comments
object.comments.active
end
end
```
## Overriding attribute methods
If you want to override any attribute, you can use:
```ruby
class PostSerializer < ActiveModel::Serializer
attributes :id, :body
has_many :comments
def body
object.body.downcase
end
end
```

View File

@ -1,3 +1,5 @@
[Back to Guides](../README.md)
# How to add pagination links
### JSON API adapter
@ -8,6 +10,10 @@ the resource is paginated and if you are using the ```JsonApi``` adapter.
If you want pagination links in your response, use [Kaminari](https://github.com/amatsuda/kaminari)
or [WillPaginate](https://github.com/mislav/will_paginate).
Although the others adapters does not have this feature, it is possible to
implement pagination links to `JSON` adapter. For more information about it,
please see in our docs
###### Kaminari examples
```ruby
@ -33,7 +39,7 @@ render json: @posts
```
```ruby
ActiveModel::Serializer.config.adapter = :json_api
ActiveModelSerializers.config.adapter = :json_api
```
ex:
@ -61,7 +67,7 @@ ex:
}
```
AMS pagination relies on a paginated collection with the methods `current_page`, `total_pages`, and `size`, such as are supported by both [Kaminari](https://github.com/amatsuda/kaminari) or [WillPaginate](https://github.com/mislav/will_paginate).
ActiveModelSerializers pagination relies on a paginated collection with the methods `current_page`, `total_pages`, and `size`, such as are supported by both [Kaminari](https://github.com/amatsuda/kaminari) or [WillPaginate](https://github.com/mislav/will_paginate).
### JSON adapter

View File

@ -1,6 +1,6 @@
# How to add root key
Add the root key to your API is quite simple with AMS. The **Adapter** is what determines the format of your JSON response. The default adapter is the ```Attributes``` which doesn't have the root key, so your response is something similar to:
Add the root key to your API is quite simple with ActiveModelSerializers. The **Adapter** is what determines the format of your JSON response. The default adapter is the ```Attributes``` which doesn't have the root key, so your response is something similar to:
```json
{
@ -13,10 +13,10 @@ Add the root key to your API is quite simple with AMS. The **Adapter** is what d
In order to add the root key you need to use the ```JSON``` Adapter, you can change this in an initializer:
```ruby
ActiveModel::Serializer.config.adapter = :json
ActiveModelSerializers.config.adapter = :json
```
You can also specify a class as adapter, as long as it complies with the AMS adapters interface.
You can also specify a class as adapter, as long as it complies with the ActiveModelSerializers adapters interface.
It will add the root key to all your serialized endpoints.
ex:

View File

@ -1,8 +1,10 @@
## Using AMS Outside Of A Controller
[Back to Guides](../README.md)
### Serializing a resource
## Using ActiveModelSerializers Outside Of A Controller
In AMS versions 0.10 or later, serializing resources outside of the controller context is fairly simple:
### Serializing a resource
In ActiveModelSerializers versions 0.10 or later, serializing resources outside of the controller context is fairly simple:
```ruby
# Create our resource
@ -16,14 +18,14 @@ serializable_resource = ActiveModel::SerializableResource.new(post, options)
# Convert your resource into json
model_json = serializable_resource.as_json
```
```
### Retrieving a Resource's Active Model Serializer
### Looking up the Serializer for a Resource
If you want to retrieve a serializer for a specific resource, you can do the following:
```ruby
# Create our resource
# Create our resource
post = Post.create(title: "Another Example", body: "So much fun.")
# Optional options parameters
@ -33,10 +35,24 @@ options = {}
serializer = ActiveModel::Serializer.serializer_for(post, options)
```
You could also retrieve the serializer via:
You could also retrieve the serializer via:
```ruby
ActiveModel::SerializableResource.new(post, options).serializer
ActiveModel::SerializableResource.new(post, options).serializer
```
Both approaches will return an instance, if any, of the resource's serializer.
Both approaches will return an instance, if any, of the resource's serializer.
## Serializing before controller render
At times, you might want to use a serializer without rendering it to the view. For those cases, you can create an instance of `ActiveModel::SerializableResource` with
the resource you want to be serialized and call `.as_json`.
```ruby
def create
message = current_user.messages.create!(message_params)
message_json = ActiveModel::SerializableResource.new(message).as_json
MessageCreationWorker.perform(message_json)
head 204
end
```

View File

@ -1,3 +1,5 @@
[Back to Guides](../README.md)
# Integrating with Ember and JSON API
- [Preparation](./ember-and-json-api.md#preparation)
@ -10,7 +12,7 @@
Note: This guide assumes that `ember-cli` is used for your ember app.
The JSON API specification calls for hyphens for multi-word separators. AMS uses underscores.
The JSON API specification calls for hyphens for multi-word separators. ActiveModelSerializers uses underscores.
To solve this, in Ember, both the adapter and the serializer will need some modifications:
### Server-Side Changes
@ -86,7 +88,7 @@ export default DS.JSONAPISerializer.extend({
## Including Nested Resources
Previously, `store.find` and `store.findRecord` did not allow specification of any query params.
The AMS default for the `include` parameter is to be `nil` meaning that if any associations are defined in your serializer, only the `id` and `type` will be in the `relationships` structure of the JSON API response.
The ActiveModelSerializers default for the `include` parameter is to be `nil` meaning that if any associations are defined in your serializer, only the `id` and `type` will be in the `relationships` structure of the JSON API response.
For more on `include` usage, see: [The JSON API include examples](./../general/adapters.md#JSON-API)
With the above modifications, you can execute code as below in order to include nested resources while doing a find query.

View File

@ -1,3 +1,5 @@
[Back to Guides](../README.md)
[![JSON API 1.0](https://img.shields.io/badge/JSON%20API-1.0-lightgrey.svg)](http://jsonapi.org/)
## JSON API Requests

View File

@ -11,11 +11,11 @@ module ActiveModel
# then extract to its own file and require it.
module ApiObjects
module JsonApi
ActiveModel::Serializer.config.jsonapi_version = '1.0'
ActiveModel::Serializer.config.jsonapi_toplevel_meta = {}
ActiveModelSerializers.config.jsonapi_version = '1.0'
ActiveModelSerializers.config.jsonapi_toplevel_meta = {}
# Make JSON API top-level jsonapi member opt-in
# ref: http://jsonapi.org/format/#document-top-level
ActiveModel::Serializer.config.jsonapi_include_toplevel_object = false
ActiveModelSerializers.config.jsonapi_include_toplevel_object = false
module_function
@ -24,15 +24,15 @@ module ActiveModel
end
def include_object?
ActiveModel::Serializer.config.jsonapi_include_toplevel_object
ActiveModelSerializers.config.jsonapi_include_toplevel_object
end
# TODO: see if we can cache this
def object
object = {
jsonapi: {
version: ActiveModel::Serializer.config.jsonapi_version,
meta: ActiveModel::Serializer.config.jsonapi_toplevel_meta
version: ActiveModelSerializers.config.jsonapi_version,
meta: ActiveModelSerializers.config.jsonapi_toplevel_meta
}
}
object[:jsonapi].reject! { |_, v| v.blank? }
@ -114,7 +114,7 @@ module ActiveModel
def resource_identifier_type_for(serializer)
return serializer._type if serializer._type
if ActiveModel::Serializer.config.jsonapi_resource_type == :singular
if ActiveModelSerializers.config.jsonapi_resource_type == :singular
serializer.object.class.model_name.singular
else
serializer.object.class.model_name.plural

View File

@ -33,11 +33,11 @@ module ActiveModel
end
def with_jsonapi_resource_type type
old_type = ActiveModel::Serializer.config.jsonapi_resource_type
ActiveModel::Serializer.config.jsonapi_resource_type = type
old_type = ActiveModelSerializers.config.jsonapi_resource_type
ActiveModelSerializers.config.jsonapi_resource_type = type
yield
ensure
ActiveModel::Serializer.config.jsonapi_resource_type = old_type
ActiveModelSerializers.config.jsonapi_resource_type = old_type
end
def test_config_plural

View File

@ -4,11 +4,11 @@ module ActiveModel
UnknownAdapterError = ::ActiveModel::Serializer::Adapter::UnknownAdapterError
def setup
@previous_adapter = ActiveModel::Serializer.config.adapter
@previous_adapter = ActiveModelSerializers.config.adapter
end
def teardown
ActiveModel::Serializer.config.adapter = @previous_adapter
ActiveModelSerializers.config.adapter = @previous_adapter
end
def test_returns_default_adapter
@ -17,23 +17,23 @@ module ActiveModel
end
def test_overwrite_adapter_with_symbol
ActiveModel::Serializer.config.adapter = :null
ActiveModelSerializers.config.adapter = :null
adapter = ActiveModel::Serializer.adapter
assert_equal ActiveModel::Serializer::Adapter::Null, adapter
ensure
ActiveModel::Serializer.config.adapter = @previous_adapter
ActiveModelSerializers.config.adapter = @previous_adapter
end
def test_overwrite_adapter_with_class
ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::Null
ActiveModelSerializers.config.adapter = ActiveModel::Serializer::Adapter::Null
adapter = ActiveModel::Serializer.adapter
assert_equal ActiveModel::Serializer::Adapter::Null, adapter
end
def test_raises_exception_if_invalid_symbol_given
ActiveModel::Serializer.config.adapter = :unknown
ActiveModelSerializers.config.adapter = :unknown
assert_raises UnknownAdapterError do
ActiveModel::Serializer.adapter
@ -41,7 +41,7 @@ module ActiveModel
end
def test_raises_exception_if_it_does_not_know_hot_to_infer_adapter
ActiveModel::Serializer.config.adapter = 42
ActiveModelSerializers.config.adapter = 42
assert_raises UnknownAdapterError do
ActiveModel::Serializer.adapter
@ -110,7 +110,7 @@ module ActiveModel
end
def test_adapter
assert_equal ActiveModel::Serializer.config.adapter, :attributes
assert_equal ActiveModelSerializers.config.adapter, :attributes
assert_equal ActiveModel::Serializer.adapter, ActiveModel::Serializer::Adapter::Attributes
end

View File

@ -33,13 +33,13 @@ module ActiveModel
case key
when :posts
assert_equal({}, options)
assert_kind_of(ActiveModel::Serializer.config.collection_serializer, serializer)
assert_kind_of(ActiveModelSerializers.config.collection_serializer, serializer)
when :bio
assert_equal({}, options)
assert_nil serializer
when :roles
assert_equal({}, options)
assert_kind_of(ActiveModel::Serializer.config.collection_serializer, serializer)
assert_kind_of(ActiveModelSerializers.config.collection_serializer, serializer)
else
flunk "Unknown association: #{key}"
end

View File

@ -4,15 +4,15 @@ module ActiveModel
class Serializer
class ConfigurationTest < Minitest::Test
def test_collection_serializer
assert_equal ActiveModel::Serializer::CollectionSerializer, ActiveModel::Serializer.config.collection_serializer
assert_equal ActiveModel::Serializer::CollectionSerializer, ActiveModelSerializers.config.collection_serializer
end
def test_array_serializer
assert_equal ActiveModel::Serializer::CollectionSerializer, ActiveModel::Serializer.config.array_serializer
assert_equal ActiveModel::Serializer::CollectionSerializer, ActiveModelSerializers.config.array_serializer
end
def test_setting_array_serializer_sets_collection_serializer
config = ActiveModel::Serializer.config
config = ActiveModelSerializers.config
old_config = config.dup
begin
assert_equal ActiveModel::Serializer::CollectionSerializer, config.collection_serializer
@ -20,12 +20,12 @@ module ActiveModel
assert_equal config.array_serializer, :foo
assert_equal config.collection_serializer, :foo
ensure
ActiveModel::Serializer.config.replace(old_config)
ActiveModelSerializers.config.replace(old_config)
end
end
def test_default_adapter
assert_equal :attributes, ActiveModel::Serializer.config.adapter
assert_equal :attributes, ActiveModelSerializers.config.adapter
end
end
end

View File

@ -6,21 +6,21 @@ module ActiveModel
class CollectionSerializerTest < Minitest::Test
def setup
@array = [1, 2, 3]
@previous_collection_serializer = ActiveModel::Serializer.config.collection_serializer
@previous_collection_serializer = ActiveModelSerializers.config.collection_serializer
end
def teardown
ActiveModel::Serializer.config.collection_serializer = @previous_collection_serializer
ActiveModelSerializers.config.collection_serializer = @previous_collection_serializer
end
def test_serializer_for_array
serializer = ActiveModel::Serializer.serializer_for(@array)
assert_equal ActiveModel::Serializer.config.collection_serializer, serializer
assert_equal ActiveModelSerializers.config.collection_serializer, serializer
end
def test_overwritten_serializer_for_array
new_collection_serializer = Class.new
ActiveModel::Serializer.config.collection_serializer = new_collection_serializer
ActiveModelSerializers.config.collection_serializer = new_collection_serializer
serializer = ActiveModel::Serializer.serializer_for(@array)
assert_equal new_collection_serializer, serializer
end

View File

@ -1,6 +1,6 @@
module SerializationTesting
def config
ActiveModel::Serializer.config
ActiveModelSerializers.config
end
private
@ -15,20 +15,20 @@ module SerializationTesting
# to pass in the +adapter+ option to <tt>ActiveModel::SerializableResource</tt>.
# e.g ActiveModel::SerializableResource.new(resource, adapter: :json_api)
def with_adapter(adapter)
old_adapter = ActiveModel::Serializer.config.adapter
ActiveModel::Serializer.config.adapter = adapter
old_adapter = ActiveModelSerializers.config.adapter
ActiveModelSerializers.config.adapter = adapter
yield
ensure
ActiveModel::Serializer.config.adapter = old_adapter
ActiveModelSerializers.config.adapter = old_adapter
end
alias_method :with_configured_adapter, :with_adapter
def with_config(hash)
old_config = config.dup
ActiveModel::Serializer.config.update(hash)
ActiveModelSerializers.config.update(hash)
yield
ensure
ActiveModel::Serializer.config.replace(old_config)
ActiveModelSerializers.config.replace(old_config)
end
def with_serializer_lookup_disabled