class JsonApiServer::AttributesBuilder

Related to sparse fieldsets. jsonapi.org/format/#fetching-sparse-fieldsets “A client MAY request that an endpoint return only specific fields in the response on a per-type basis by including a fields parameter.”

Use this class to build the attributes section in JSON API serializers. It will only add attributes defined in fields (sparse fieldset). If fields is nil (no requested sparse fieldset), it will add all attributes.

Examples

This:

/articles?include=author&fields[articles]=title,body,phone&fields[people]=name

converts to:

{'articles' => ['title', 'body', 'phone'], 'people' => ['name']}

When fields is an array, only fields in the array are added:

AttributesBuilder.new(['title', 'body', 'phone'])
  .add('title', @record.title)
  .add('body',  @record.body)
  .add_if('phone', @record.phone, -> { admin? })  # conditionally adding
  .add('isbn', @record.isbn)  # not in sparse fields array
  .attributes

  # when non-admin
  # => {
  #      'title' => 'Everyone Poops',
  #      'body' => 'Taro Gomi'
  #   }

  #    or...

  # when admin
  # => {
  #      'title' => 'Everyone Poops',
  #       'body' => 'Taro Gomi',
  #       'phone' => '123-4567',
  #   }

When fields is nil, all attributes are added.

AttributesBuilder.new
 .add_multi(@record, 'title', 'body')
 .add_if('phone', @record.phone, -> { admin? })  # conditionally adding
 .add('isbn', @record.isbn)
 .attributes

 # when non-admin
 # => {
 #      'title' => 'Everyone Poops',
 #      'body' => 'Taro Gomi',
 #      'isbn' => '5555555'
 #    }

 #    or...

 # when admin
 # => {
 #       'title' => 'Everyone Poops',
 #       'body' => 'Taro Gomi',
 #       'phone' => '123-4567',
 #       'isbn' => '5555555'
 #    }

Attributes

fields[R]

(Array or nil) fields (sparse fieldset) array passed in initialize.

Public Class Methods

new(fields = nil) click to toggle source
  • fields - Array of fields to display for a type. Defaults to nil. When nil, all fields are permitted.

# File lib/json_api_server/attributes_builder.rb, line 72
def initialize(fields = nil)
  @hash = {}
  @fields = fields
  @fields.map!(&:to_s) if @fields.respond_to?(:map)
end

Public Instance Methods

add(name, value) click to toggle source

Adds attribute if attribute name is in fields array.

i.e,

JsonApiServer::AttributesBuilder.new(fields)
 .add('name', @object.name)
 .attributes
# File lib/json_api_server/attributes_builder.rb, line 85
def add(name, value)
  @hash[name.to_s] = value if add_attr?(name)
  self
end
add_if(name, value, proc) click to toggle source

Adds attribute if attribute name is in fields array and proc returns true.

i.e,

JsonApiServer::AttributesBuilder.new(fields)
 .add_if('email', @object.email, -> { admin? })
 .attributes
# File lib/json_api_server/attributes_builder.rb, line 109
def add_if(name, value, proc)
  @hash[name] = value if add_attr?(name) && proc.call == true
  self
end
add_multi(object, *attrs) click to toggle source

Add multiple attributes.

i.e,

JsonApiServer::AttributesBuilder.new(fields)
 .add_multi(@object, 'name', 'email', 'logins')
 .attributes
# File lib/json_api_server/attributes_builder.rb, line 97
def add_multi(object, *attrs)
  attrs.each { |attr| add(attr, object.send(attr)) }
  self
end
attributes() click to toggle source

Returns attributes as a hash.

i.e.,

{
  'title' => 'Everyone Poops',
  'body' => 'Taro Gomi',
  'phone' => '123-4567',
  'isbn' => '5555555'
}
# File lib/json_api_server/attributes_builder.rb, line 123
def attributes
  @hash
end

Protected Instance Methods

add_attr?(name) click to toggle source

Returns true if @fields is not defined. If @fields is defined, returns true if attribute name is included in the @fields array.

# File lib/json_api_server/attributes_builder.rb, line 131
def add_attr?(name)
  @fields.respond_to?(:include?) ? @fields.include?(name.to_s) : true
end