class FunWithJsonApi::FindCollectionFromDocument

Attributes

deserializer[R]
document[R]

Public Class Methods

find(...) click to toggle source
# File lib/fun_with_json_api/find_collection_from_document.rb, line 6
def self.find(...)
  new(...).find
end
new(document, deserializer) click to toggle source
# File lib/fun_with_json_api/find_collection_from_document.rb, line 16
def initialize(document, deserializer)
  @document = FunWithJsonApi.sanitize_document(document)
  @deserializer = deserializer
end

Public Instance Methods

document_ids() click to toggle source
# File lib/fun_with_json_api/find_collection_from_document.rb, line 37
def document_ids
  @document_id ||= document['data'].map { |item| item['id'] }
end
document_is_valid_collection?() click to toggle source
# File lib/fun_with_json_api/find_collection_from_document.rb, line 49
def document_is_valid_collection?
  document.key?('data') && document['data'].is_a?(Array)
end
document_types() click to toggle source
# File lib/fun_with_json_api/find_collection_from_document.rb, line 41
def document_types
  @document_type ||= document['data'].map { |item| item['type'] }.uniq
end
find() click to toggle source
# File lib/fun_with_json_api/find_collection_from_document.rb, line 21
def find
  raise build_invalid_document_error unless document_is_valid_collection?

  # Skip the checks, no point running through them for an empty array
  return [] if document_ids.empty?

  # Ensure the document matches the expected resource
  check_document_types_match_deserializer!

  # Load resource from id value
  deserializer.load_collection_from_id_values(document_ids).tap do |collection|
    check_collection_contains_all_requested_resources!(collection)
    check_collection_is_authorised!(collection)
  end
end
resource_type() click to toggle source
# File lib/fun_with_json_api/find_collection_from_document.rb, line 45
def resource_type
  @resource_type ||= deserializer.type
end

Private Instance Methods

build_invalid_document_error() click to toggle source
# File lib/fun_with_json_api/find_collection_from_document.rb, line 68
def build_invalid_document_error
  payload = ExceptionPayload.new
  payload.pointer = '/data'
  payload.detail = 'Expected data to be an Array of resources'
  Exceptions::InvalidDocument.new(
    "Expected root data element with an Array: #{document.inspect}",
    payload
  )
end
build_invalid_document_types_error() click to toggle source
# File lib/fun_with_json_api/find_collection_from_document.rb, line 78
def build_invalid_document_types_error
  message = 'Expected type for each item to match expected resource type'\
            ": '#{resource_type}'"
  payload = document['data'].each_with_index.map do |data, index|
    next if data['type'] == resource_type
    ExceptionPayload.new(
      pointer: "/data/#{index}/type",
      detail: document_type_does_not_match_endpoint_message(data['type'])
    )
  end.reject(&:nil?)
  Exceptions::InvalidDocumentType.new(message, payload)
end
check_collection_contains_all_requested_resources!(collection) click to toggle source
# File lib/fun_with_json_api/find_collection_from_document.rb, line 55
def check_collection_contains_all_requested_resources!(collection)
  SchemaValidators::CheckCollectionHasAllMembers.call(collection, document_ids, deserializer)
end
check_collection_is_authorised!(collection) click to toggle source
# File lib/fun_with_json_api/find_collection_from_document.rb, line 59
def check_collection_is_authorised!(collection)
  SchemaValidators::CheckCollectionIsAuthorised.call(collection, document_ids, deserializer)
end
check_document_types_match_deserializer!() click to toggle source
# File lib/fun_with_json_api/find_collection_from_document.rb, line 63
def check_document_types_match_deserializer!
  invalid_document_types = document_types.reject { |type| type == resource_type }
  raise build_invalid_document_types_error if invalid_document_types.any?
end
document_type_does_not_match_endpoint_message(type) click to toggle source
# File lib/fun_with_json_api/find_collection_from_document.rb, line 91
def document_type_does_not_match_endpoint_message(type)
  I18n.t(
    :invalid_document_type,
    type: type,
    resource: resource_type,
    scope: 'fun_with_json_api.find_collection_from_document'
  )
end