Class: Dato::Repo

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

Constant Summary collapse

IDENTITY_REGEXP =
/\{\(.*?definitions%2F(.*?)%2Fdefinitions%2Fidentity\)}/
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
125
126
127
128
129
130
131
# File 'lib/dato/repo.rb', line 34

def method_missing(method, *args, &block)
  link = schema.links.find do |link|
    METHOD_NAMES.fetch(link.rel, link.rel).to_sym == method.to_sym
  end

  return super if !link

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

  (args.size >= min_arguments_count) or
    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 link.method == :delete
    query_string = args.shift || {}

  elsif link.method == :get
    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(type, 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

    while !job_result do
      begin
        sleep(1)
        job_result = client.job_result.find(response[:data][:id])
      rescue ApiError => error
        if error.response[:status] != 404
          raise error
        end
      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
  else
    if options.fetch(:deserialize_response, true)
      JsonApiDeserializer.new(link.target_schema).deserialize(response)
    else
      response
    end
  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