class Shamu::JsonApi::Context
Attributes
Public Class Methods
@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
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 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
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
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
@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
@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
# 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
# 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
# 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