class SimpleJSONAPIClient::Base

Attributes

connection[R]
context[R]
id[R]
included[R]
input_relationships[R]

Public Class Methods

_attributes() click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 13
def _attributes
  @_attributes ||= {}
end
attributes(*attrs) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 17
def attributes(*attrs)
  attrs.each do |attr|
    define_method(attr) { attributes[attr] }
    define_method("#{attr}=") { |x| attributes[attr] = x }
    _attributes[attr] = true
  end
end
create(opts) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 56
def create(opts)
  operation(:create_request, :singular, opts)
end
delete(opts) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 64
def delete(opts)
  operation(:delete_request, :empty, opts)
  true
end
fetch(opts) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 46
def fetch(opts)
  operation(:fetch_request, :singular, opts)
end
fetch_all(opts) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 50
def fetch_all(opts)
  Redirection::FetchAll.new(opts) do |request_opts|
    operation(:fetch_all_request, :plural, request_opts)
  end
end
has_many(relationship_name, opts) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 32
def has_many(relationship_name, opts)
  model_class = opts.fetch(:class) { opts.fetch(:class_name) }
  define_relationship_methods!(relationship_name)
  relationships[relationship_name.to_sym] =
    Relationships::HasManyRelationship.new(model_class)
end
has_one(relationship_name, opts) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 39
def has_one(relationship_name, opts)
  define_relationship_methods!(relationship_name)
  model_class = opts.fetch(:class) { opts.fetch(:class_name) }
  relationships[relationship_name.to_sym] =
    Relationships::HasOneRelationship.new(model_class)
end
include_records(included_hash, records) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 89
def include_records(included_hash, records)
  records.to_a.each do |record|
    included_hash[{ 'id' => record['id'], 'type' => record['type'] }] = record
  end
end
interpreted_included(records, included) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 82
def interpreted_included(records, included)
  {}.tap do |included_hash|
    include_records(included_hash, records)
    include_records(included_hash, included)
  end
end
meta(*attrs) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 25
def meta(*attrs)
  attrs.each do |attr|
    define_method(attr) { meta[attr] }
    define_method("#{attr}=") { |x| meta[attr] = x }
  end
end
model_from(record, included, connection, context = nil) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 69
def model_from(record, included, connection, context = nil)
  return unless record
  new(
    meta: record['meta'],
    id: record['id'],
    attributes: record.fetch('attributes', {}),
    relationships: record.fetch('relationships', {}),
    context: context,
    included: included,
    connection: connection
  )
end
new(meta: nil, id:, attributes: nil, relationships: nil, included: {}, connection:, context: nil) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 249
def initialize(meta: nil, id:, attributes: nil, relationships: nil, included: {}, connection:, context: nil)
  @meta = Utils.symbolize_keys(meta) if meta
  @id = id
  @included = included
  @connection = connection
  @context = context
  @attributes = Utils.symbolize_keys(attributes) if attributes
  @input_relationships = relationships
end
relationships() click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 9
def relationships
  @relationships ||= {}
end
template(id: nil, attributes:, relationships: {}) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 95
def template(id: nil, attributes:, relationships: {})
  data = {
    type: self::TYPE,
    attributes: attributes,
    relationships: interpreted_relationships(relationships)
  }
  data[:id] = id if id
  { data: data }
end
update(opts) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 60
def update(opts)
  operation(:update_request, :singular, opts)
end

Private Class Methods

create_request(connection:, url_opts: {}, url: self::COLLECTION_URL % url_opts, attributes: {}, relationships: {}, **attrs) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 119
def create_request(connection:,
                   url_opts: {},
                   url: self::COLLECTION_URL % url_opts,
                   attributes: {},
                   relationships: {},
                   **attrs)
  attributes, relationships = extract_attrs(attrs, attributes, relationships)
  body = template(attributes: attributes, relationships: relationships)
  connection.post(url, body)
end
define_relationship_methods!(relationship_name) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 107
def define_relationship_methods!(relationship_name)
  define_method(relationship_name) { relationships[relationship_name] }
  define_method("#{relationship_name}=") { |x| relationships[relationship_name] = x }
end
delete_request(connection:, url_opts: {}) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 146
def delete_request(connection:, url_opts: {})
  connection.delete(self::INDIVIDUAL_URL % url_opts)
end
extract_attrs(attrs, attributes, relationships) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 174
def extract_attrs(attrs, attributes, relationships)
  attrs.each do |attr, value|
    if _attributes.key?(attr)
      attributes[attr] = value
    elsif self.relationships.key?(attr)
      relationships[attr] = value
    else
      raise ArgumentError, %{Invalid attribute "#{attr}"}
    end
  end
  [attributes, relationships]
end
fetch_all_request(connection:, url_opts: {}, url: self::COLLECTION_URL % url_opts, filter_opts: {}, page_opts: {}, includes: []) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 161
def fetch_all_request(connection:,
                      url_opts: {},
                      url: self::COLLECTION_URL % url_opts,
                      filter_opts: {},
                      page_opts: {},
                      includes: [])
  params = {}
  params[:include] = includes.join(',') unless includes.empty?
  params[:filter] = filter_opts unless filter_opts.empty?
  params[:page] = page_opts unless page_opts.empty?
  connection.get(url, params)
end
fetch_request(connection:, url_opts: {}, filter_opts: {}, url: self::INDIVIDUAL_URL % url_opts, includes: []) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 150
def fetch_request(connection:,
                  url_opts: {},
                  filter_opts: {},
                  url: self::INDIVIDUAL_URL % url_opts,
                  includes: [])
  params = {}
  params[:include] = includes.join(',') unless includes.empty?
  params[:filter] = filter_opts unless filter_opts.empty?
  connection.get(url, params)
end
handling_error(response) { || ... } click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 238
def handling_error(response)
  if response.success?
    yield
  else
    raise ::SimpleJSONAPIClient::Errors::APIError.generate(response)
  end
end
interpret_empty_response(response, connection) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 207
def interpret_empty_response(response, connection)
end
interpret_plural_response(response, connection) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 195
def interpret_plural_response(response, connection)
  body = response.body
  records = body['data']
  included = interpreted_included(records, body['included'])
  {
    'links' => body['links'],
    'data' => records.map { |record|
      model_from(record, included, connection, response)
    }
  }
end
interpret_singular_response(response, connection) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 187
def interpret_singular_response(response, connection)
  body = response.body
  record = body['data']
  records = [record].compact
  included = interpreted_included(records, body['included'])
  model_from(record, included, connection, response)
end
interpreted_relationships(relationships) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 211
def interpreted_relationships(relationships)
  relationships.transform_values { |value|
    if (relationship = relationship_from(value))
      { data: relationship }
    end
  }
end
operation(request_method, response_type, opts) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 112
def operation(request_method, response_type, opts)
  response = send(request_method, opts)
  handling_error(response) do
    send(:"interpret_#{response_type}_response", response, opts[:connection])
  end
end
relationship_from(value) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 228
def relationship_from(value)
  if value.respond_to?(:to_relationship)
    value.to_relationship
  elsif value.respond_to?(:map)
    value.map(&:to_relationship)
  elsif !value.nil?
    raise ArgumentError, "#{value} cannot be converted to relationship!"
  end
end
update_request(connection:, id:, url_opts: {}, attributes: {}, relationships: {}, **attrs) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 130
def update_request(connection:,
                   id:,
                   url_opts: {},
                   attributes: {},
                   relationships: {},
                   **attrs)
  attributes, relationships = extract_attrs(attrs, attributes, relationships)
  connection.patch(self::INDIVIDUAL_URL % url_opts) do |request|
    request.body = template(
      id: id,
      attributes: attributes,
      relationships: relationships
    )
  end
end

Public Instance Methods

as_json() click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 302
def as_json
  self.class.template(
    id: id,
    attributes: attributes,
    relationships: relationships
  )
end
attributes() click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 267
def attributes
  @attributes ||= loaded_record.attributes
end
delete() click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 295
def delete
  self.class.delete(
    connection: connection,
    url_opts: { id: id }
  )
end
inspect() click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 314
def inspect
  parsed_attributes = attributes.map { |key, value| "#{key}=#{value.inspect}" }.join(' ')
  parsed_attributes = " #{parsed_attributes}" unless parsed_attributes.empty?
  parsed_relationships = relationships.map { |key, value| "#{key}=#{value.inspect}" }.join(' ')
  parsed_relationships = " #{parsed_relationships}" unless parsed_relationships.empty?
  "#<#{self.class.name} id=#{id}#{parsed_attributes}#{parsed_relationships}>"
end
meta() click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 271
def meta
  @meta ||= loaded_record.meta
end
relationships() click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 275
def relationships
  @relationships ||=
    begin
      if input_relationships
        relationships_to_models(Utils.symbolize_keys(input_relationships))
      else
        loaded_record.relationships
      end
    end
end
same_record_as?(other) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 263
def same_record_as?(other)
  to_relationship == other.to_relationship
end
to_json(*args) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 310
def to_json(*args)
  as_json.to_json(*args)
end
to_relationship() click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 259
def to_relationship
  { type: self.class::TYPE, id: id }
end
update(**attrs) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 286
def update(**attrs)
   self.class.update(
     connection: connection,
     id: id,
     url_opts: { id: id },
     **attrs
   )
end

Private Instance Methods

loaded_record() click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 332
def loaded_record
  @loaded_record ||= self.class.fetch(connection: connection, url_opts: { id: id })
end
relationships_to_models(relationships) click to toggle source
# File lib/simple_jsonapi_client/base.rb, line 325
def relationships_to_models(relationships)
  relationships.each_with_object({}) do |(relationship, info), memo|
    next unless implementation = self.class.relationships[relationship]
    memo[relationship] = implementation.call(info, included, connection)
  end
end