simpleweb/active_model_serializers

Name: active_model_serializers

Owner: Simpleweb

Description: ActiveModel::Serializer implementation and Rails hooks

Forked from: rails-api/active_model_serializers

Created: 2015-11-12 13:29:03.0

Updated: 2015-11-12 13:29:04.0

Pushed: 2015-11-12 05:03:01.0

Homepage:

Size: 7924

Language: Ruby

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

ActiveModelSerializers

Build Status

Windows Build Status - Build status

ActiveModelSerializers brings convention over configuration to your JSON generation.

AMS does this 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. Check how to change the adapter in the sections bellow.

Documentation

Master

RELEASE CANDIDATE, PLEASE READ

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 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.

Example

Given two models, a Post(title: string, body: text) and a Comment(name: string, body: text, post_id: integer), you will have two serializers:

s PostSerializer < ActiveModel::Serializer
che key: 'posts', expires_in: 3.hours
tributes :title, :body

s_many :comments

and

s CommentSerializer < ActiveModel::Serializer
tributes :name, :body

longs_to :post

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:

veModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::JsonApi

or

veModel::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:

veModel::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:

s PostSerializer < ActiveModel::Serializer
tributes :id, :body

look up :subject on the model, but use +title+ in the JSON
tribute :subject, :key => :title
s_many :comments

In your controllers, when you use render :json, Rails will now first search for a serializer for the object and use it if available.

s PostsController < ApplicationController
f show
@post = Post.find(params[:id])

render json: @post
d

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:
nder json: @post, serializer: PostPreviewSerializer
2. For an array resource:
e the default `CollectionSerializer`, which will use `each_serializer` to
rialize each element
er json: @posts, each_serializer: PostPreviewSerializer

, you can explicitly provide the collection serializer as well
er json: @posts, serializer: CollectionSerializer, each_serializer: PostPreviewSerializer
Meta

If you want a meta attribute in your response, specify it in the render call:

er json: @post, meta: { total: 10 }

The key can be customized using meta_key option.

er 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.

create
essage = current_user.messages.create!(message_params)
ssageCreationWorker.perform(serialized_message)
ad 204


serialized_message
tiveModel::SerializableResource.new(@message).serializable_hash

Overriding association methods

If you want to override any association, you can use:

s PostSerializer < ActiveModel::Serializer
tributes :id, :body

s_many :comments

f comments
object.comments.active
d

Overriding attribute methods

If you want to override any attribute, you can use:

s PostSerializer < ActiveModel::Serializer
tributes :id, :body

s_many :comments

f body
object.body.downcase
d

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. 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.

nder @posts, include: ['author', 'comments', 'comments.author']
or
nder @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.

nder @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.

nder @posts, include: 'author.comments.**'

The JSON API specifies that the user may supply a parameter specifying which related resources are to be included:

nder @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.

Installation

Add this line to your application's Gemfile:

'active_model_serializers'

And then execute:

ndle
Creating a Serializer

The easiest way to create a new serializer is to generate a new resource, which will generate a serializer at the same time:

ils 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:

ils g serializer post

The generated serializer will contain basic attributes and has_many/has_one/belongs_to declarations, based on the model. For example:

s PostSerializer < ActiveModel::Serializer
tributes :title, :body

s_many :comments
s_one :author

and

s CommentSerializer < ActiveModel::Serializer
tributes :name, :body

longs_to :post_id

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:

s_many :comments, serializer: CommentPreviewSerializer

And you can change the JSON key that the serializer should use for a particular association:

s_many :comments, key: :reviews
Pagination

Pagination links will be included in your response automatically as long as the resource is paginated using Kaminari or WillPaginate 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.

Caching

To cache a serializer, call `cacheand pass its options. The options are the same options of ``ActiveSupport::Cache::Store`, plus akey`` 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 `showrequest 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.

e(options = nil) # options: ```{key, expires_in, compress, force, race_condition_ttl}```

Take the example bellow:

s PostSerializer < ActiveModel::Serializer
che key: 'post', expires_in: 3.hours
tributes :title, :body

s_many :comments

On this example every `Postobject 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 `onlyor ``except``` option on cache method.

[NOTE] Cache serializers will be used at their relationships

Example:

s PostSerializer < ActiveModel::Serializer
che key: 'post', expires_in: 3.hours, only: [:title]
tributes :title, :body

s_many :comments

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).

Getting Help

If you find a bug, please report an Issue.

If you have a question, please post to Stack Overflow.

Thanks!

Contributing

See CONTRIBUTING.md


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.