class Shamu::JsonApi::Context

Attributes

all_resources[R]
fields[R]
included_resources[R]
namespaces[R]
presenters[R]

Public Class Methods

new( fields: nil, namespaces: [], presenters: {} ) click to toggle source

@param [Hash<Symbol,Array>] fields explicitly declare the attributes and

resources that should be included in the response. The hash consists
of a keys of the resource types and values as an array of fields to
be included.

A String value will be split on `,` to allow for easy parsing of
HTTP query parameters.

@param [Array<String>] namespaces to look for resource {Presenter

presenters}. See {#find_presenter}.

@param [Hash<Class,Class>] presenters a hash that maps resource classes

to the presenter class to use when building responses. See
{#find_presenter}.
# File lib/shamu/json_api/context.rb, line 19
def initialize( fields: nil, namespaces: [], presenters: {} )
  @included_resources = {}
  @all_resources = Set.new
  @fields = parse_fields( fields )
  @namespaces = Array( namespaces )
  @presenters = presenters || {}
end

Public Instance Methods

collect_included_resources() click to toggle source

Collects all the currently included resources and resets the queue.

@return [Array<Object,Hash>] returns the the resource and presentation

options from each resource buffered with {#include_resource}.
# File lib/shamu/json_api/context.rb, line 52
def collect_included_resources
  included = included_resources.dup
  @included_resources = {}
  included
end
find_presenter( resource ) click to toggle source

Find a {Presenter} that can write the resource to a {ResourceBuilder}.

  • First looks for any explicit presenter given to the constructor that maps the resource's class to a specific presenter.

  • Next, looks through each of the namespaces given to the constructor. For each namespace, looks for a `Namespace::#{ resource.class.name }Presenter`. Will also check `resource.class.model_name.name` if available.

  • Fails with a {NoPresenter} error if a presenter cannot be found.

@param [Object] resource to present. @return [Class] the {Presenter} class to use. @raise [NoPresenter] if a presenter cannot be found.

# File lib/shamu/json_api/context.rb, line 89
def find_presenter( resource )
  presenter   = presenters[ resource.class ]
  presenter ||= presenters[ resource.class ] = find_namespace_presenter( resource )

  fail NoPresenter.new( resource, namespaces ) unless presenter

  presenter
end
include_field?( type, name, default = true ) click to toggle source

Check to see if the field should be included in the JSON API output.

@param [Symbol] type the resource type in question. @param [Symbol] name of the field on the resouce in question. @param [Boolean] default true if the field should be included by default

when no explicit fields have been selected.

@return [Boolean] true if the field should be included.

# File lib/shamu/json_api/context.rb, line 70
def include_field?( type, name, default = true )
  return default unless type_fields = fields[ type ]

  type_fields.include?( name )
end
include_resource( resource, presenter = nil, &block ) click to toggle source

Add an included resource for a compound response.

If no `presenter` and no block are provided a default presenter will be obtained by calling {#find_presenter}.

@param [Object] resource to be serialized. @param [Class] presenter tpresenter {Presenter} class to use to

serialize the `resource`. If not provided a default {Presenter} will
be chosen.

@yield (builder) @yieldparam [ResourceBuilder] builder to write embedded resource to.

# File lib/shamu/json_api/context.rb, line 38
def include_resource( resource, presenter = nil, &block )
  return if all_resources.include?( resource )

  all_resources << resource
  included_resources[resource] ||= begin
    presenter ||= find_presenter( resource ) unless block
    { presenter: presenter, block: block }
  end
end
included_resources?() click to toggle source

@return [Boolean] true if there are any pending included resources.

# File lib/shamu/json_api/context.rb, line 59
def included_resources?
  included_resources.any?
end
params_meta() click to toggle source

@return [Hash] of request param options to be output in the response meta.

# File lib/shamu/json_api/context.rb, line 99
def params_meta
  return unless fields.any?

  { fields: fields }
end

Private Instance Methods

find_namespace_presenter( resource ) click to toggle source
# File lib/shamu/json_api/context.rb, line 128
def find_namespace_presenter( resource )
  presenter   = find_namespace_presenter_for( resource.class.name.demodulize )
  presenter ||= find_namespace_presenter_for( resource.model_name.element.camelize )       if resource.respond_to?( :model_name )        # rubocop:disable Metrics/LineLength
  presenter ||= find_namespace_presenter_for( resource.class.model_name.element.camelize ) if resource.class.respond_to?( :model_name )  # rubocop:disable Metrics/LineLength
  presenter
end
find_namespace_presenter_for( name ) click to toggle source
# File lib/shamu/json_api/context.rb, line 135
def find_namespace_presenter_for( name )
  name = "#{ name }Presenter".to_sym

  namespaces.each do |namespace|
    begin
      return "#{ namespace }::#{ name }".constantize
    rescue NameError # rubocop:disable Lint/HandleExceptions
    end
  end

  nil
end
parse_fields( raw ) click to toggle source
# File lib/shamu/json_api/context.rb, line 113
def parse_fields( raw )
  return {} unless raw

  raw = raw.to_unsafe_hash if raw.respond_to?( :to_unsafe_hash )

  raw.each_with_object( {} ) do |(type, fields), parsed|
    fields = fields.split( "," ) if fields.is_a?( String )

    parsed[ type.to_sym ] = fields.map do |field|
      field = field.strip if field.is_a? String
      field.to_sym
    end
  end
end