class FastJsonapi::Relationship

Attributes

cached[R]
conditional_proc[R]
id_method_name[R]
key[R]
lazy_load_data[R]
meta[R]
name[R]
object_block[R]
object_method_name[R]
owner[R]
polymorphic[R]
record_type[R]
relationship_type[R]
serializer[R]
transform_method[R]

Public Class Methods

new( owner:, key:, name:, id_method_name:, record_type:, object_method_name:, object_block:, serializer:, relationship_type:, polymorphic:, conditional_proc:, transform_method:, links:, meta:, cached: false, lazy_load_data: false ) click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 5
def initialize(
  owner:,
  key:,
  name:,
  id_method_name:,
  record_type:,
  object_method_name:,
  object_block:,
  serializer:,
  relationship_type:,
  polymorphic:,
  conditional_proc:,
  transform_method:,
  links:,
  meta:,
  cached: false,
  lazy_load_data: false
)
  @owner = owner
  @key = key
  @name = name
  @id_method_name = id_method_name
  @record_type = record_type
  @object_method_name = object_method_name
  @object_block = object_block
  @serializer = serializer
  @relationship_type = relationship_type
  @cached = cached
  @polymorphic = polymorphic
  @conditional_proc = conditional_proc
  @transform_method = transform_method
  @links = links || {}
  @meta = meta || {}
  @lazy_load_data = lazy_load_data
  @record_types_for = {}
  @serializers_for_name = {}
end

Public Instance Methods

fetch_associated_object(record, params) click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 55
def fetch_associated_object(record, params)
  return FastJsonapi.call_proc(object_block, record, params) unless object_block.nil?

  record.send(object_method_name)
end
include_relationship?(record, serialization_params) click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 61
def include_relationship?(record, serialization_params)
  if conditional_proc.present?
    FastJsonapi.call_proc(conditional_proc, record, serialization_params)
  else
    true
  end
end
serialize(record, included, serialization_params, output_hash) click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 43
def serialize(record, included, serialization_params, output_hash)
  if include_relationship?(record, serialization_params)
    empty_case = relationship_type == :has_many ? [] : nil

    output_hash[key] = {}
    output_hash[key][:data] = ids_hash_from_record_and_relationship(record, serialization_params) || empty_case unless lazy_load_data && !included

    add_meta_hash(record, serialization_params, output_hash) if meta.present?
    add_links_hash(record, serialization_params, output_hash) if links.present?
  end
end
serializer_for(record, serialization_params) click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 69
def serializer_for(record, serialization_params)
  # TODO: Remove this, dead code...
  if @static_serializer
    @static_serializer

  elsif polymorphic
    name = polymorphic[record.class] if polymorphic.is_a?(Hash)
    name ||= record.class.name
    serializer_for_name(name)

  elsif serializer.is_a?(Proc)
    FastJsonapi.call_proc(serializer, record, serialization_params)

  elsif object_block
    serializer_for_name(record.class.name)

  else
    # TODO: Remove this, dead code...
    raise "Unknown serializer for object #{record.inspect}"
  end
end
static_record_type() click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 96
def static_record_type
  initialize_static_serializer unless @initialized_static_serializer
  @static_record_type
end
static_serializer() click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 91
def static_serializer
  initialize_static_serializer unless @initialized_static_serializer
  @static_serializer
end

Private Instance Methods

add_meta_hash(record, params, output_hash) click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 158
def add_meta_hash(record, params, output_hash)
  output_hash[key][:meta] = if meta.is_a?(Proc)
                              FastJsonapi.call_proc(meta, record, params)
                            else
                              meta
                            end
end
compute_static_record_type() click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 231
def compute_static_record_type
  if polymorphic
    nil
  elsif record_type
    run_key_transform(record_type)
  elsif @static_serializer
    run_key_transform(@static_serializer.record_type)
  end
end
compute_static_serializer() click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 182
def compute_static_serializer
  if polymorphic
    # polymorphic without a specific serializer --
    # the serializer is determined on a record-by-record basis
    nil

  elsif serializer.is_a?(Symbol) || serializer.is_a?(String)
    # a serializer was explicitly specified by name -- determine the serializer class
    serializer_for_name(serializer)

  elsif serializer.is_a?(Proc)
    # the serializer is a Proc to be executed per object -- not static
    nil

  elsif serializer
    # something else was specified, e.g. a specific serializer class -- return it
    serializer

  elsif object_block
    # an object block is specified without a specific serializer --
    # assume the objects might be different and infer the serializer by their class
    nil

  else
    # no serializer information was provided -- infer it from the relationship name
    serializer_name = name.to_s
    serializer_name = serializer_name.singularize if relationship_type.to_sym == :has_many
    serializer_for_name(serializer_name)
  end
end
fetch_id(record, params) click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 138
def fetch_id(record, params)
  if object_block.present?
    object = FastJsonapi.call_proc(object_block, record, params)
    return object.map { |item| item.public_send(id_method_name) } if object.respond_to? :map

    return object.try(id_method_name)
  end
  record.public_send(id_method_name)
end
id_hash(id, record_type, default_return = false) click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 130
def id_hash(id, record_type, default_return = false)
  if id.present?
    { id: id.to_s, type: record_type }
  else
    default_return ? { id: nil, type: record_type } : nil
  end
end
id_hash_from_record(record, params) click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 119
def id_hash_from_record(record, params)
  associated_record_type = record_type_for(record, params)
  id_hash(record.public_send(id_method_name), associated_record_type)
end
ids_hash(ids, record_type) click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 124
def ids_hash(ids, record_type)
  return ids.map { |id| id_hash(id, record_type) } if ids.respond_to? :map

  id_hash(ids, record_type) # ids variable is just a single id here
end
ids_hash_from_record_and_relationship(record, params = {}) click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 103
def ids_hash_from_record_and_relationship(record, params = {})
  initialize_static_serializer unless @initialized_static_serializer

  return ids_hash(fetch_id(record, params), @static_record_type) if @static_record_type

  return unless associated_object = fetch_associated_object(record, params)

  if associated_object.respond_to? :map
    return associated_object.map do |object|
      id_hash_from_record object, params
    end
  end

  id_hash_from_record associated_object, params
end
initialize_static_serializer() click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 174
def initialize_static_serializer
  return if @initialized_static_serializer

  @static_serializer = compute_static_serializer
  @static_record_type = compute_static_record_type
  @initialized_static_serializer = true
end
record_type_for(record, serialization_params) click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 217
def record_type_for(record, serialization_params)
  # if the record type is static, return it
  return @static_record_type if @static_record_type

  # if not, use the record type of the serializer, and memoize the transformed version
  serializer = serializer_for(record, serialization_params)
  # if the serializer has record_type_block -> use it instead
  if serializer.record_type_block.present?
    @record_types_for[serializer] ||= serializer.record_type_block.call(record)
  else
    @record_types_for[serializer] ||= run_key_transform(serializer.record_type)
  end
end
run_key_transform(input) click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 166
def run_key_transform(input)
  if transform_method.present?
    input.to_s.send(*transform_method).to_sym
  else
    input.to_sym
  end
end
serializer_for_name(name) click to toggle source
# File lib/fast_jsonapi/relationship.rb, line 213
def serializer_for_name(name)
  @serializers_for_name[name] ||= owner.serializer_for(name)
end