class FunWithJsonApi::CollectionManager

Abstract Handles updating a collection relationship. Override the ‘insert`, `remove` and `replace` methods, or provide a block that perfoms the desired action on the collection.

Attributes

deserializer[R]
parent_resource[R]

Public Class Methods

new(parent_resource, deserializer_class, deserializer_options) click to toggle source
# File lib/fun_with_json_api/collection_manager.rb, line 11
def initialize(parent_resource, deserializer_class, deserializer_options)
  @parent_resource = parent_resource
  @deserializer = deserializer_class.create(deserializer_options)
end

Public Instance Methods

failure_message_for_resource(resource, failure_message_or_callable) click to toggle source
# File lib/fun_with_json_api/collection_manager.rb, line 75
def failure_message_for_resource(resource, failure_message_or_callable)
  resource_id = deserializer.format_resource_id(resource)
  failure_message = failure_message_or_callable
  if failure_message.respond_to?(:call)
    failure_message = failure_message.call(resource_id)
  end
  failure_message || default_invalid_resource_message(resource_id)
end
insert_record(_record) click to toggle source

Inserts a single record into a collection Must return true for a successful update, or return false for any failures

# File lib/fun_with_json_api/collection_manager.rb, line 18
def insert_record(_record)
  raise build_relationship_not_supported_exception(
    "Override #{self.class.name}#insert_record",
    insert_not_supported_message
  )
end
insert_records(collection, failure_message_or_callable = nil) click to toggle source

Inserts all records from a collection into the parent resource

Will attempt to call ‘insert_record` for each item in the `collection`. If false is received for any `insert_record` call, an exception with a payload will be raised after all items have been iterated through

You need to reverse all changes made in the event of an exception, wrapping an an ActiveRecord::Base.transaction block will usually work

Action is not supported unless ‘insert_records` or the `insert_record` method is overridden

# File lib/fun_with_json_api/collection_manager.rb, line 44
def insert_records(collection, failure_message_or_callable = nil)
  update_collection_items(collection, failure_message_or_callable) do |record|
    insert_record(record)
  end
end
remove_record(_record) click to toggle source

Removes a single record into a collection Must return true for a successful update, or return false for any failures

# File lib/fun_with_json_api/collection_manager.rb, line 27
def remove_record(_record)
  raise build_relationship_not_supported_exception(
    "Override #{self.class.name}#remove_record",
    remove_not_supported_message
  )
end
remove_records(collection, failure_message_or_callable = nil) click to toggle source

Removes all records from a collection into the parent resource

Will attempt to call ‘remove_record` for each item in the `collection`. If false is received for any `remove_record` call, an exception with a payload will be raised after all items have been iterated through

You need to reverse all changes made in the event of an exception, wrapping an an ActiveRecord::Base.transaction block will usually work

Action is not supported unless ‘remove_records` or the `remove_record` method is overridden

# File lib/fun_with_json_api/collection_manager.rb, line 60
def remove_records(collection, failure_message_or_callable = nil)
  update_collection_items(collection, failure_message_or_callable) do |record|
    remove_record(record)
  end
end
replace_all_records(_collection) click to toggle source

Replaces all records

# File lib/fun_with_json_api/collection_manager.rb, line 67
def replace_all_records(_collection)
  # Action is not supported unless overridden
  raise build_relationship_not_supported_exception(
    "Override #{self.class.name}#replace_all_records to implement replace all",
    replace_all_not_supported_message
  )
end

Protected Instance Methods

default_invalid_resource_message(resource_id) click to toggle source
# File lib/fun_with_json_api/collection_manager.rb, line 110
def default_invalid_resource_message(resource_id)
  I18n.t(
    'invalid_resource',
    resource: deserializer.type,
    resource_id: resource_id,
    scope: 'fun_with_json_api.collection_manager'
  )
end
insert_not_supported_message() click to toggle source
# File lib/fun_with_json_api/collection_manager.rb, line 86
def insert_not_supported_message
  I18n.t(
    'insert_not_supported',
    resource: deserializer.type,
    scope: 'fun_with_json_api.collection_manager'
  )
end
remove_not_supported_message() click to toggle source
# File lib/fun_with_json_api/collection_manager.rb, line 94
def remove_not_supported_message
  I18n.t(
    'remove_not_supported',
    resource: deserializer.type,
    scope: 'fun_with_json_api.collection_manager'
  )
end
replace_all_not_supported_message() click to toggle source
# File lib/fun_with_json_api/collection_manager.rb, line 102
def replace_all_not_supported_message
  I18n.t(
    'replace_all_not_supported',
    resource: deserializer.type,
    scope: 'fun_with_json_api.collection_manager'
  )
end
update_collection_items(collection, failure_message_or_callable = nil) { |resource| ... } click to toggle source
# File lib/fun_with_json_api/collection_manager.rb, line 119
def update_collection_items(collection, failure_message_or_callable = nil)
  failed_resources_hash = {}
  collection.each_with_index.map do |resource, index|
    failed_resources_hash[index] = resource unless yield(resource)
  end.reject(&:nil?)
  if failed_resources_hash.any?
    raise_invalid_resource_exception(failed_resources_hash, failure_message_or_callable)
  end
end

Private Instance Methods

build_invalid_resource_exception_payload(failed_resources_hash, failure_message_or_callable) click to toggle source
# File lib/fun_with_json_api/collection_manager.rb, line 144
def build_invalid_resource_exception_payload(failed_resources_hash, failure_message_or_callable)
  failed_resources_hash.map do |index, resource|
    failure_message = failure_message_for_resource(resource, failure_message_or_callable)
    ExceptionPayload.new(detail: failure_message, pointer: "/data/#{index}")
  end
end
build_relationship_not_supported_exception(debug_message, exception_message) click to toggle source
# File lib/fun_with_json_api/collection_manager.rb, line 131
def build_relationship_not_supported_exception(debug_message, exception_message)
  Exceptions::RelationshipMethodNotSupported.new(
    debug_message, ExceptionPayload.new(detail: exception_message)
  )
end
raise_invalid_resource_exception(failed_resources_hash, failure_message_or_callable) click to toggle source
# File lib/fun_with_json_api/collection_manager.rb, line 137
def raise_invalid_resource_exception(failed_resources_hash, failure_message_or_callable)
  raise Exceptions::InvalidResource.new(
    'Unable to update relationship due to errors with collection',
    build_invalid_resource_exception_payload(failed_resources_hash, failure_message_or_callable)
  )
end