module HALPresenter::Serializer

Public Class Methods

included(base) click to toggle source
# File lib/hal_presenter/serializer.rb, line 34
def self.included(base)
  base.extend(ClassMethods)
end

Public Instance Methods

to_collection(resources = [], **options) click to toggle source
# File lib/hal_presenter/serializer.rb, line 48
def to_collection(resources = [], **options)
  unless can_serialize_collection?
    raise Error,
      "Trying to serialize a collection using #{self} which has no collection info. " \
      "Add a 'collection' spec to the serializer or use another serializer"
  end
  options = options.dup
  options[:paginate] = HALPresenter.paginate unless options.key? :paginate
  options[:_depth] ||= 0
  hash = to_collection_hash(resources, options)
  move_curies_to_root! hash
  return hash if options[:as_hash]

  JSON.generate(hash)
end
to_hal(resource = nil, **options) click to toggle source
# File lib/hal_presenter/serializer.rb, line 38
def to_hal(resource = nil, **options)
  options = options.dup
  options[:_depth] ||= 0
  hash = to_hash(resource, options)
  move_curies_to_root! hash
  return hash if options[:as_hash]

  JSON.generate(hash)
end

Protected Instance Methods

serialize_attributes(resource, policy, options) click to toggle source
# File lib/hal_presenter/serializer.rb, line 99
def serialize_attributes(resource, policy, options)
  _serialize_attributes(attributes, resource, policy, options)
end
serialize_curies(resource, policy, options) click to toggle source
# File lib/hal_presenter/serializer.rb, line 107
def serialize_curies(resource, policy, options)
  _serialize_curies(curies, resource, options)
end
serialize_embedded(resource, policy, options) click to toggle source
# File lib/hal_presenter/serializer.rb, line 111
def serialize_embedded(resource, policy, options)
  _serialize_embedded(embedded, resource, policy, options)
end
to_collection_hash(resources, options) click to toggle source
# File lib/hal_presenter/serializer.rb, line 77
def to_collection_hash(resources, options)
  policy = policy_for(nil, options)
  properties = collection_properties
  attributes = properties.attributes
  links = properties.links
  curies = properties.curies
  embedded = properties.embedded
  {}.tap do |serialized|
    serialized.merge!  _serialize_attributes(attributes, resources, policy, options)
    serialized.merge! _serialize_links(links, curies, resources, policy, options)
    Pagination.paginate!(serialized, resources) if options[:paginate]

    # Embedded from collection block
    serialized.merge! _serialize_embedded(embedded, resources, policy, options)

    # Embedded resources
    serialized_resources = resources.map { |resource| to_hash(resource, options.dup) }
    serialized[:_embedded] ||= {}
    serialized[:_embedded].merge!(properties.name => serialized_resources)
  end
end
to_hash(resource, options) click to toggle source
# File lib/hal_presenter/serializer.rb, line 66
def to_hash(resource, options)
  policy = policy_for(resource, options)
  {}.tap do |serialized|
    serialized.merge! serialize_attributes(resource, policy, options)
    serialized.merge! serialize_links(resource, policy, options)
    serialized.merge! serialize_embedded(resource, policy, options)

    run_post_serialize_hook!(resource, options, serialized)
  end
end

Private Instance Methods

_serialize_attributes(attributes, resource, policy, options) click to toggle source
# File lib/hal_presenter/serializer.rb, line 133
def _serialize_attributes(attributes, resource, policy, options)
  attributes.each_with_object({}) do |attribute, hash|
    next unless attribute.nested_depth_ok? options[:_depth]
    next if policy && !policy.attribute?(attribute.name)
    hash[attribute.name] = attribute.value(resource, options)
  end
end
_serialize_curies(curies, resource, options) click to toggle source
# File lib/hal_presenter/serializer.rb, line 163
def _serialize_curies(curies, resource, options)
  curies.each_with_object([]) do |curie, array|
    next unless curie.nested_depth_ok? options[:_depth]
    hash = curie.to_h(resource, options)
    array << hash unless hash.empty?
  end
end
_serialize_embedded(embedded, object, policy, options) click to toggle source
# File lib/hal_presenter/serializer.rb, line 171
def _serialize_embedded(embedded, object, policy, options)
  serialized = embedded.each_with_object({}) do |embed, hash|
    next unless embed.nested_depth_ok? options[:_depth]
    next if policy && !policy.embed?(embed.name)
    resource = embed.value(object, options) or next
    presenter = embed.presenter_class
    embed_options = options.dup
    embed_options[:_depth] += 1
    hash[embed.name] = 
      if resource.is_a? Array
        _serialize_embedded_collection(resource, presenter, embed_options)
      else
        presenter ||= HALPresenter.lookup_presenter(resource)
        presenter.to_hash(resource, embed_options)
      end
  end
  return {} if serialized.empty?
  { _embedded: serialized }
end
_serialize_embedded_collection(resources, presenter, options) click to toggle source
# File lib/hal_presenter/serializer.rb, line 191
def _serialize_embedded_collection(resources, presenter, options)
  clazz = resources.first.class
  presenter ||= HALPresenter.lookup_presenter(clazz)
  if presenter.nil?
    raise Serializer::Error,
      "No presenter specified to handle serializing embedded #{clazz}"
  end
  if presenter.can_serialize_collection?
    presenter.to_collection_hash(resources, options)
  else
    resources.map do |resrc|
      presenter.to_hash(resrc, options)
    end
  end
end
move_curies_to_root!(hash) click to toggle source
# File lib/hal_presenter/serializer.rb, line 117
def move_curies_to_root!(hash)
  return if Hash(hash).empty?

  curie_collection = CurieCollection.extract_from!(hash)
  return if curie_collection.empty?

  hash[:_links] ||= {}
  hash[:_links][:curies] = curie_collection.to_a
end
policy_for(resource, options) click to toggle source
# File lib/hal_presenter/serializer.rb, line 207
def policy_for(resource, options)
  policy_class&.new(options[:current_user], resource, options)
end
run_post_serialize_hook!(resource, options, serialized) click to toggle source
# File lib/hal_presenter/serializer.rb, line 128
def run_post_serialize_hook!(resource, options, serialized)
  hook = post_serialize_hook
  hook&.run(resource, options, serialized)
end