class JsonApiServer::ResourceSerializer

Description

Serializer class for a resource. Subclasses JsonApiServer::BaseSerializer.

Example class:

class CommentSerializer < JsonApiServer::ResourceSerializer
  resource_type 'comments'

  def links
    { self: File.join(base_url, "/comments/#{@object.id}") }
  end

  def data
    {}.tap do |h|
      h['type'] = self.class.type
      h['id'] = @object.id
      h['attributes'] = attributes
      h['relationships'] = inclusions.relationships if inclusions?
    end
  end

  def included
    inclusions.included if inclusions?
  end

  protected

  def attributes
    attributes_builder
      .add_multi(@object, 'title', 'comment')
      .add('created_at', @object.created_at.try(:iso8601, 9))
      .add('updated_at', @object.updated_at.try(:iso8601, 9))
      .attributes
  end

  def inclusions
    @inclusions ||= begin
      if relationship?('comment.author')
        relationships_builder.relate('author', user_serializer(@object.author))
      end
      if relationship?('comment.author.links')
        relationships_builder.include('author', user_serializer(@object.author),
                                      relate: { include: [:links] })
      end
      relationships_builder
    end
  end

  def user_serializer(user, as_json_options = { include: [:data] })
    ::UserSerializer.new(
      user,
      includes: includes,
      fields: fields,
      as_json_options: as_json_options
    )
  end
end

Create an instance from builder:

builder = JsonApiServer::Builder.new(request, Comment.find(params[:id]))
  .add_include(['comment.author', 'comment.author.links'])
  .add_fields

serializer = CommentSerializer.from_builder(builder)

Attributes

fields[R]

Hash. Fields requested by user. From the 'fields' param. Extracted via JsonApiServer::Fields#sparse_fields which is also available through JsonApiServer::Builder#sparse_fields. Defaults to nil. Set in initializer options.

i.e.,

GET /articles?include=author&fields[articles]=title,body&fields[people]=name becomes:
fields = {'articles' => ['title', 'body'], 'people' => ['name']}
includes[R]

Array. Relationships to include. Array of strings. From the 'include' param. Extracted via JsonApiServer::Include#includes which is also available through JsonApiServer::Builder#includes. Defaults to nil. Set in initializer options.

i.e.,

GET /articles?include=comments.author,publisher becomes:
includes = ['comments.author', 'publisher']

Public Class Methods

from_builder(builder, **options) click to toggle source

object, includes and fields will be extracted from it.

# File lib/json_api_server/resource_serializer.rb, line 124
def from_builder(builder, **options)
  opts = options.merge(fields: options[:fields] || builder.sparse_fields,
                       includes: options[:includes] || builder.includes,
                       paginator: options[:paginator] || builder.paginator,
                       filter: options[:filter] || builder.filter)
  new(builder.query, opts)
end
new(object, **options) click to toggle source
Calls superclass method JsonApiServer::BaseSerializer::new
# File lib/json_api_server/resource_serializer.rb, line 96
def initialize(object, **options)
  super(options)
  @object = object
  @includes = options[:includes]
  @fields = options[:fields]
end
resource_type(type) click to toggle source

'type' used in relationship_data.

# File lib/json_api_server/resource_serializer.rb, line 112
def resource_type(type)
  @type = type
end
type() click to toggle source

'type' used in relationship_data and data. i.e.:

"data": {"type": "articles", "id": 2}
# File lib/json_api_server/resource_serializer.rb, line 107
def type
  @type || type_from_class_name
end

Protected Class Methods

type_from_class_name() click to toggle source

Get type from class name.

# File lib/json_api_server/resource_serializer.rb, line 135
def type_from_class_name
  @type_from_class_name ||= begin
    class_name = name.split('::').last
    class_name.downcase!
    class_name.gsub!(/serializer/, '')
    class_name.pluralize
  end
end

Public Instance Methods

relationship_data() click to toggle source

Content when as_json_options {include: [:relationship_data]} is specified. Defaults to { 'type' => <resource_type>, 'id' => <@object.id> }. resource_type can be set with class method resource_type, otherwise it will be guessed from serializer class name.

# File lib/json_api_server/resource_serializer.rb, line 149
def relationship_data
  id = @object.try(:id) || @object.try(:[], :id)
  { 'type' => self.class.type, 'id' => id }
end

Protected Instance Methods

attributes_builder() click to toggle source

Instance of JsonApiServer::AttributesBuilder for the class's resource 'type'.

i.e.,

self.attributes_builder  # => attributes_builder_for(self.class.type)
  .add('title', @object.title)
  .add('body', @object.body)
  .add('created_at', @object.created_at)
# File lib/json_api_server/resource_serializer.rb, line 183
def attributes_builder
  @attributes_builder ||= attributes_builder_for(self.class.type)
end
attributes_builder_for(type) click to toggle source

Returns a new instance of JsonApiServer::AttributesBuilder for the specified fields type.

  • type - the resource type.

i.e.,

# GET /articles?include=author&fields[articles]=title,body&fields[people]=name becomes:
# fields = {'articles' => ['title', 'body'], 'people' => ['name']}

self.attributes_builder_for('articles')
  .add('title', @object.title)
  .add('body', @object.body)
  .add('created_at', @object.created_at)
# File lib/json_api_server/resource_serializer.rb, line 171
def attributes_builder_for(type)
  JsonApiServer::AttributesBuilder.new(fields_for(type))
end
fields_for(type) click to toggle source

Returns the fields for a specific type. i.e., fields_for('articles') or nil if type doesn't exist or fields is nil.

# File lib/json_api_server/resource_serializer.rb, line 241
def fields_for(type)
  @fields.respond_to?(:key) ? @fields[type.to_s] : nil
end
inclusions?() click to toggle source

Returns true if there are requested inclusions. False otherwise.

# File lib/json_api_server/resource_serializer.rb, line 235
def inclusions?
  @includes.respond_to?(:any?) && @includes.any?
end
meta_builder() click to toggle source

Instance of JsonApiServer::MetaBuilder.

i.e.,

self.meta_builder
   .add('total_records', 35)
...
self.meta_builder
   .add('paging', 'showing 11 - 20')
   .meta # => { 'total_records': 35, 'paging': 'showing 11 - 20' }
# File lib/json_api_server/resource_serializer.rb, line 198
def meta_builder
  @meta_builder ||= JsonApiServer::MetaBuilder.new
end
rb()
relationship?(relationship) click to toggle source

Returns true if relationship is in includes array.

  • relationship - Name of relationship. String or symbol.

i.e.,

# GET /articles?include=comment.author,publisher becomes:
# includes = ['comment.author', 'publisher']

self.relationship?('comment.author') # => true
self.relationship?('addresses') # => false
# File lib/json_api_server/resource_serializer.rb, line 230
def relationship?(relationship)
  @includes.respond_to?(:include?) && @includes.include?(relationship.to_s)
end
relationships_builder() click to toggle source

Instance of JsonApiServer::RelationshipsBuilder.

i.e.,

self.relationships_builder
   .relate(...)
   .relate_if(...)
   .relate_each(...)

self.relationships_builder.relationships # get relationships section
self.relationships_builder.included # get included section
# File lib/json_api_server/resource_serializer.rb, line 213
def relationships_builder
  @relationships_builder ||= JsonApiServer::RelationshipsBuilder.new
end
Also aliased as: rb