class Dato::Repo

Constants

IDENTITY_REGEXP
METHOD_NAMES

Attributes

client[R]
schema[R]
type[R]

Public Class Methods

new(client, type, schema) click to toggle source
# File lib/dato/repo.rb, line 18
def initialize(client, type, schema)
  @client = client
  @type = type
  @schema = schema
end

Public Instance Methods

respond_to_missing?(method, include_private = false) click to toggle source
Calls superclass method
# File lib/dato/repo.rb, line 24
def respond_to_missing?(method, include_private = false)
  respond_to_missing = schema.links.any? do |link|
    METHOD_NAMES.fetch(link.rel, link.rel).to_sym == method.to_sym
  end

  respond_to_missing || super
end

Private Instance Methods

method_missing(method, *args, &block) click to toggle source
Calls superclass method
# File lib/dato/repo.rb, line 34
def method_missing(method, *args, &block)
  link = schema.links.find do |ilink|
    METHOD_NAMES.fetch(ilink.rel, ilink.rel).to_sym == method.to_sym
  end

  return super unless link

  min_arguments_count = [
    link.href.scan(IDENTITY_REGEXP).size,
    link.schema && link.method != :get ? 1 : 0,
  ].reduce(0, :+)

  (args.size >= min_arguments_count) ||
    raise(ArgumentError, "wrong number of arguments (given #{args.size}, expected #{min_arguments_count})")

  placeholders = []

  url = link["href"].gsub(IDENTITY_REGEXP) do |_stuff|
    placeholder = args.shift.to_s
    placeholders << placeholder
    placeholder
  end

  body = nil
  query_string = nil

  if %i[post put].include?(link.method)
    body = link.schema ? args.shift : {}
    query_string = args.shift || {}

  elsif %i[get delete].include?(link.method)
    query_string = args.shift || {}
  end

  options = args.any? ? args.shift.symbolize_keys : {}

  if link.schema && %i[post put].include?(link.method) && options.fetch(:serialize_response, true)
    body = JsonApiSerializer.new(link: link).serialize(
      body,
      link.method == :post ? nil : placeholders.last,
    )
  end

  response = if %i[post put].include?(link.method)
               client.send(link.method, url, body, query_string)
             elsif link.method == :delete
               client.delete(url, query_string)
             elsif link.method == :get
               if options.fetch(:all_pages, false)
                 Paginator.new(client, url, query_string).response
               else
                 client.get(url, query_string)
               end
             end

  if response && response[:data] && response[:data].is_a?(Hash) && response[:data][:type] == "job"
    job_result = nil

    until job_result
      begin
        sleep(1)
        job_result = client.job_result.find(response[:data][:id])
      rescue ApiError => e
        raise e if e.response[:status] != 404
      end
    end

    if job_result[:status] < 200 || job_result[:status] >= 300
      error = ApiError.new(
        status: job_result[:status],
        body: JSON.dump(job_result[:payload]),
      )

      puts "===="
      puts error.message
      puts "===="

      raise error
    end

    if options.fetch(:deserialize_response, true)
      JsonApiDeserializer.new(link.job_schema).deserialize(job_result[:payload])
    else
      job_result.payload
    end
  elsif options.fetch(:deserialize_response, true)
    JsonApiDeserializer.new(link.target_schema).deserialize(response)
  else
    response
  end
end