Class: Dato::Repo

Inherits:
Object
  • Object
show all
Defined in:
lib/dato/repo.rb

Constant Summary collapse

IDENTITY_REGEXP =
/\{\(.*?definitions%2F(.*?)%2Fdefinitions%2Fidentity\)}/.freeze
METHOD_NAMES =
{
  "instances" => :all,
  "self" => :find,
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client, type, schema) ⇒ Repo

Returns a new instance of Repo.



18
19
20
21
22
# File 'lib/dato/repo.rb', line 18

def initialize(client, type, schema)
  @client = client
  @type = type
  @schema = schema
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object (private)



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# 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

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



9
10
11
# File 'lib/dato/repo.rb', line 9

def client
  @client
end

#schemaObject (readonly)

Returns the value of attribute schema.



9
10
11
# File 'lib/dato/repo.rb', line 9

def schema
  @schema
end

#typeObject (readonly)

Returns the value of attribute type.



9
10
11
# File 'lib/dato/repo.rb', line 9

def type
  @type
end

Instance Method Details

#respond_to_missing?(method, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


24
25
26
27
28
29
30
# 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