active_model_serializers/docs/general/serializers.md

4.4 KiB

Back to Guides

Serializers

Given a serializer class:

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
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
def title 'A Different Title' end
{ title: 'A Different Title' }

PR please for conditional attributes:)

Associations

::has_one

e.g.

has_one :bio
has_one :blog, key: :site
has_one :maker, virtual_value: { id: 1 }

::has_many

e.g.

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.

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.

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.

# Uses a custom non-time-based cache key
def cache_key
  "#{self.class.name.downcase}/#{self.id}"
end

Other

::type

The ::type method defines the JSONAPI type that will be rendered for this serializer. It either takes a String or Symbol as parameter.

Note: This method is useful only when using the :json_api adapter.

Examples:

class UserProfileSerializer < ActiveModel::Serializer
  type 'profile'
end
class AuthorProfileSerializer < ActiveModel::Serializer
  type :profile
end

With the :json_api adapter, the previous serializers would be rendered as:

{
  "data": {
    "id": "1",
    "type": "profile"
  }
}
link :self do
  href "https://example.com/link_author/#{object.id}"
end
link :author { link_author_url(object) }
link :link_authors { link_authors_url }
link :other, 'https://example.com/resource'
link :posts { link_author_posts_url(object) }

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

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

Overriding association methods

To override an association, call has_many, has_one or belongs_to with a block:

class PostSerializer < ActiveModel::Serializer
  has_many :comments do
    object.comments.active
  end
end

Overriding attribute methods

To override an attribute, call attribute with a block:

class PostSerializer < ActiveModel::Serializer
  attribute :body do
    object.body.downcase
  end
end