class JSONAPI::Processor

Attributes

context[R]
operation_type[R]
params[R]
resource_klass[R]
result[R]
result_options[R]

Public Class Methods

new(resource_klass, operation_type, params) click to toggle source
# File lib/jsonapi/processor.rb, line 22
def initialize(resource_klass, operation_type, params)
  @resource_klass = resource_klass
  @operation_type = operation_type
  @params = params
  @context = params[:context]
  @result = nil
  @result_options = {}
end

Public Instance Methods

create_resource() click to toggle source
# File lib/jsonapi/processor.rb, line 229
def create_resource
  include_directives = params[:include_directives]
  fields = params[:fields]
  serializer = params[:serializer]

  data = params[:data]
  resource = resource_klass.create(context)
  result = resource.replace_fields(data)

  find_options = {
      context: context,
      fields: fields,
      filters: { resource_klass._primary_key => resource.id },
      include_directives: include_directives
  }

  resource_set = find_resource_set(resource_klass,
                                   include_directives,
                                   find_options)

  resource_set.populate!(serializer, context, find_options)

  return JSONAPI::ResourceSetOperationResult.new((result == :completed ? :created : :accepted), resource_set, result_options)
end
create_to_many_relationships() click to toggle source
# File lib/jsonapi/processor.rb, line 314
def create_to_many_relationships
  resource_id = params[:resource_id]
  relationship_type = params[:relationship_type].to_sym
  data = params[:data]

  resource = resource_klass.find_by_key(resource_id, context: context)
  result = resource.create_to_many_links(relationship_type, data)

  return JSONAPI::OperationResult.new(result == :completed ? :no_content : :accepted, result_options)
end
find() click to toggle source
# File lib/jsonapi/processor.rb, line 42
def find
  filters = params[:filters]
  include_directives = params[:include_directives]
  sort_criteria = params[:sort_criteria]
  paginator = params[:paginator]
  fields = params[:fields]
  serializer = params[:serializer]

  verified_filters = resource_klass.verify_filters(filters, context)

  find_options = {
    context: context,
    sort_criteria: sort_criteria,
    paginator: paginator,
    fields: fields,
    filters: verified_filters,
    include_directives: include_directives
  }

  resource_set = find_resource_set(resource_klass,
                                   include_directives,
                                   find_options)

  resource_set.populate!(serializer, context, find_options)

  page_options = result_options
  if (JSONAPI.configuration.top_level_meta_include_record_count || (paginator && paginator.class.requires_record_count))
    page_options[:record_count] = resource_klass.count(verified_filters,
                                                       context: context,
                                                       include_directives: include_directives)
  end

  if (JSONAPI.configuration.top_level_meta_include_page_count && paginator && page_options[:record_count])
    page_options[:page_count] = paginator ? paginator.calculate_page_count(page_options[:record_count]) : 1
  end

  if JSONAPI.configuration.top_level_links_include_pagination && paginator
    page_options[:pagination_params] = paginator.links_page_params(page_options.merge(fetched_resources: resource_set))
  end

  return JSONAPI::ResourcesSetOperationResult.new(:ok, resource_set, page_options)
end
find_resource_set(resource_klass, include_directives, options) click to toggle source
# File lib/jsonapi/processor.rb, line 369
def find_resource_set(resource_klass, include_directives, options)
  include_related = include_directives.include_directives[:include_related] if include_directives

  resource_id_tree = find_resource_id_tree(resource_klass, options, include_related)

  JSONAPI::ResourceSet.new(resource_id_tree)
end
process() click to toggle source
# File lib/jsonapi/processor.rb, line 31
def process
  run_callbacks :operation do
    run_callbacks operation_type do
      @result = send(operation_type)
    end
  end

rescue JSONAPI::Exceptions::Error => e
  @result = JSONAPI::ErrorsOperationResult.new(e.errors[0].code, e.errors)
end
remove_resource() click to toggle source
# File lib/jsonapi/processor.rb, line 254
def remove_resource
  resource_id = params[:resource_id]

  resource = resource_klass.find_by_key(resource_id, context: context)
  result = resource.remove

  return JSONAPI::OperationResult.new(result == :completed ? :no_content : :accepted, result_options)
end
remove_to_many_relationships() click to toggle source
# File lib/jsonapi/processor.rb, line 336
def remove_to_many_relationships
  resource_id = params[:resource_id]
  relationship_type = params[:relationship_type].to_sym
  associated_keys = params[:associated_keys]

  resource = resource_klass.find_by_key(resource_id, context: context)

  complete = true
  associated_keys.each do |key|
    result = resource.remove_to_many_link(relationship_type, key)
    if complete && result != :completed
      complete = false
    end
  end
  return JSONAPI::OperationResult.new(complete ? :no_content : :accepted, result_options)
end
remove_to_one_relationship() click to toggle source
# File lib/jsonapi/processor.rb, line 353
def remove_to_one_relationship
  resource_id = params[:resource_id]
  relationship_type = params[:relationship_type].to_sym

  resource = resource_klass.find_by_key(resource_id, context: context)
  result = resource.remove_to_one_link(relationship_type)

  return JSONAPI::OperationResult.new(result == :completed ? :no_content : :accepted, result_options)
end
replace_fields() click to toggle source
# File lib/jsonapi/processor.rb, line 263
def replace_fields
  resource_id = params[:resource_id]
  include_directives = params[:include_directives]
  fields = params[:fields]
  serializer = params[:serializer]

  data = params[:data]

  resource = resource_klass.find_by_key(resource_id, context: context)

  result = resource.replace_fields(data)

  find_options = {
      context: context,
      fields: fields,
      filters: { resource_klass._primary_key => resource.id },
      include_directives: include_directives
  }

  resource_set = find_resource_set(resource_klass,
                                   include_directives,
                                   find_options)

  resource_set.populate!(serializer, context, find_options)

  return JSONAPI::ResourceSetOperationResult.new((result == :completed ? :ok : :accepted), resource_set, result_options)
end
replace_polymorphic_to_one_relationship() click to toggle source
# File lib/jsonapi/processor.rb, line 302
def replace_polymorphic_to_one_relationship
  resource_id = params[:resource_id]
  relationship_type = params[:relationship_type].to_sym
  key_value = params[:key_value]
  key_type = params[:key_type]

  resource = resource_klass.find_by_key(resource_id, context: context)
  result = resource.replace_polymorphic_to_one_link(relationship_type, key_value, key_type)

  return JSONAPI::OperationResult.new(result == :completed ? :no_content : :accepted, result_options)
end
replace_to_many_relationships() click to toggle source
# File lib/jsonapi/processor.rb, line 325
def replace_to_many_relationships
  resource_id = params[:resource_id]
  relationship_type = params[:relationship_type].to_sym
  data = params.fetch(:data)

  resource = resource_klass.find_by_key(resource_id, context: context)
  result = resource.replace_to_many_links(relationship_type, data)

  return JSONAPI::OperationResult.new(result == :completed ? :no_content : :accepted, result_options)
end
replace_to_one_relationship() click to toggle source
# File lib/jsonapi/processor.rb, line 291
def replace_to_one_relationship
  resource_id = params[:resource_id]
  relationship_type = params[:relationship_type].to_sym
  key_value = params[:key_value]

  resource = resource_klass.find_by_key(resource_id, context: context)
  result = resource.replace_to_one_link(relationship_type, key_value)

  return JSONAPI::OperationResult.new(result == :completed ? :no_content : :accepted, result_options)
end
show() click to toggle source
# File lib/jsonapi/processor.rb, line 85
def show
  include_directives = params[:include_directives]
  fields = params[:fields]
  id = params[:id]
  serializer = params[:serializer]

  key = resource_klass.verify_key(id, context)

  find_options = {
    context: context,
    fields: fields,
    filters: { resource_klass._primary_key => key },
    include_directives: include_directives
  }

  resource_set = find_resource_set(resource_klass,
                                   include_directives,
                                   find_options)

  fail JSONAPI::Exceptions::RecordNotFound.new(id) if resource_set.resource_klasses.empty?
  resource_set.populate!(serializer, context, find_options)

  return JSONAPI::ResourceSetOperationResult.new(:ok, resource_set, result_options)
end
show_relationship() click to toggle source
# File lib/jsonapi/processor.rb, line 110
def show_relationship
  parent_key = params[:parent_key]
  relationship_type = params[:relationship_type].to_sym
  paginator = params[:paginator]
  sort_criteria = params[:sort_criteria]
  include_directives = params[:include_directives]
  fields = params[:fields]

  parent_resource = resource_klass.find_by_key(parent_key, context: context)

  find_options = {
      context: context,
      sort_criteria: sort_criteria,
      paginator: paginator,
      fields: fields,
      include_directives: include_directives
  }

  resource_id_tree = find_related_resource_id_tree(resource_klass,
                                                   JSONAPI::ResourceIdentity.new(resource_klass, parent_key),
                                                   relationship_type,
                                                   find_options,
                                                   nil)

  return JSONAPI::RelationshipOperationResult.new(:ok,
                                                  parent_resource,
                                                  resource_klass._relationship(relationship_type),
                                                  resource_id_tree.fragments.keys,
                                                  result_options)
end

Private Instance Methods

find_resource_id_tree(resource_klass, find_options, include_related) click to toggle source
# File lib/jsonapi/processor.rb, line 400
def find_resource_id_tree(resource_klass, find_options, include_related)
  options = find_options
  options[:cache] = resource_klass.caching?

  fragments = resource_klass.find_fragments(find_options[:filters], options)

  primary_resource_id_tree = PrimaryResourceIdTree.new
  primary_resource_id_tree.add_resource_fragments(fragments, include_related)

  load_included(resource_klass, primary_resource_id_tree, include_related, options)

  primary_resource_id_tree
end
find_resource_id_tree_from_resource_relationship(resource, relationship_name, find_options, include_related) click to toggle source
# File lib/jsonapi/processor.rb, line 414
def find_resource_id_tree_from_resource_relationship(resource, relationship_name, find_options, include_related)
  relationship = resource.class._relationship(relationship_name)

  options = find_options.except(:include_directives)
  options[:cache] = relationship.resource_klass.caching?

  fragments = resource.class.find_related_fragments([resource.identity], relationship_name, options)

  primary_resource_id_tree = PrimaryResourceIdTree.new
  primary_resource_id_tree.add_resource_fragments(fragments, include_related)

  load_included(resource_klass, primary_resource_id_tree, include_related, options)

  primary_resource_id_tree
end
load_included(resource_klass, source_resource_id_tree, include_related, options) click to toggle source
# File lib/jsonapi/processor.rb, line 430
def load_included(resource_klass, source_resource_id_tree, include_related, options)
  source_rids = source_resource_id_tree.fragments.keys

  include_related.try(:each_key) do |key|
    relationship = resource_klass._relationship(key)
    relationship_name = relationship.name.to_sym

    find_related_resource_options = options.except(:filters, :sort_criteria, :paginator)
    find_related_resource_options[:sort_criteria] = relationship.resource_klass.default_sort
    find_related_resource_options[:cache] = resource_klass.caching?

    related_fragments = resource_klass.find_included_fragments(
      source_rids, relationship_name, find_related_resource_options
    )

    related_resource_id_tree = source_resource_id_tree.fetch_related_resource_id_tree(relationship)
    related_resource_id_tree.add_resource_fragments(related_fragments, include_related[key][include_related])

    # Now recursively get the related resources for the currently found resources
    load_included(relationship.resource_klass,
                  related_resource_id_tree,
                  include_related[relationship_name][:include_related],
                  options)
  end
end