Module: Distant::Base::ClassMethods

Defined in:
lib/distant/base.rb

Instance Method Summary collapse

Instance Method Details

#belongs_to(singular, route) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/distant/base.rb', line 81

def belongs_to(singular, route)
  @belongs_to << singular.to_sym
  define_method(singular) do
    foreign_key_attr = singular.to_s + '_id'
    foreign_key_value = self.send(foreign_key_attr)
    path_generator, captures = self.class.path_closure_generator(route)
    path_args = captures.map{|x| {x.to_sym => send(x)}}.reduce({}, :merge)
    path = path_generator.call(path_args)
    headers = Distant.config.default_headers('')
                .merge(Distant.config.auth_headers(''))
    class_ref = Kernel.const_get self.class.to_s.deconstantize + '::' + singular.to_s.classify
    response_data = class_ref.preprocess_response connection.get(path, headers: headers)
    class_ref.marshal(response_data)
  end
end

#belongs_to_relsObject



44
45
46
# File 'lib/distant/base.rb', line 44

def belongs_to_rels
  @belongs_to
end

#connectionObject



36
37
38
# File 'lib/distant/base.rb', line 36

def connection
  @@connection ||= Distant::Connection.configure( Distant.config )
end

#get(name, route) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/distant/base.rb', line 52

def get(name, route)
  define_singleton_method(name) do |*args|
    path_generator, captures = self.path_closure_generator(route)
    path = path_generator.call(*args)
    headers = Distant.config.default_headers('')
                .merge(Distant.config.auth_headers(''))
    response_data = preprocess_response connection.get(path, headers: headers)
    if response_data.is_a? Array
      response_data.map{ |item| marshal(item) }
    else
      marshal(response_data)
    end
  end
end

#has_many(plural, route) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/distant/base.rb', line 67

def has_many(plural, route)
  @has_many << plural.to_sym
  define_method(plural) do
    path_generator, captures = self.class.path_closure_generator(route)
    path_args = captures.map{|x| {x.to_sym => send(x)}}.reduce({}, :merge)
    path = path_generator.call(path_args)
    headers = Distant.config.default_headers('')
                .merge(Distant.config.auth_headers(''))
    class_ref = Kernel.const_get self.class.to_s.deconstantize + '::' + plural.to_s.singularize.classify
    response_data = class_ref.preprocess_response connection.get(path, headers: headers)
    response_data.map{ |item| class_ref.marshal(item) }
  end
end

#has_many_relsObject



40
41
42
# File 'lib/distant/base.rb', line 40

def has_many_rels
  @has_many
end

#init_class_varsObject



30
31
32
33
34
# File 'lib/distant/base.rb', line 30

def init_class_vars
  @has_many = [ ]
  @belongs_to = [ ]
  @translator = Distant::Translator.new
end

#marshal(data) ⇒ Object



48
49
50
# File 'lib/distant/base.rb', line 48

def marshal(data)
  self.new(data)
end

#path_closure_generator(route) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/distant/base.rb', line 97

def path_closure_generator(route)
  # Look for /foo/:bar/:bux and return ['bar', 'bux']
  captures = route.scan(%r{:([^/\{\}\:\-]+)}).flatten

  # Look for /foo/:bar/:bux and return '/foo/%{bar}/%{bux}'
  template = route.gsub(%r{:([^/\{\}\:\-]+)}, "%{#{$1}}")

  # Convert '/foo/%{bar}/%{bux}' to /foo/123/456 with {bar: 123, bux: 456}
  proc = class_eval "    Proc.new do |\#{captures.map{|cap| \"\#{cap}:\"}.join(', ')}|\n      template % {\n        \#{captures.map{ |cap| cap + \": \" + cap }.join(', ')}\n      }\n    end\n  EOF\n\n  return proc, captures\nend\n"

#preprocess_response(response) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/distant/base.rb', line 116

def preprocess_response(response)
  case response.code
  when 200..299
    parsed = JSON.parse(response.body, symbolize_names: true)
    parsed.is_a?(Array) ?
      parsed.map{ |item| translator.translate_from_hash(item) }
      : translator.translate_from_hash(parsed)
  else
    raise Distant::ApiError.new response
  end
end

#translate(&block) ⇒ Object



132
133
134
135
# File 'lib/distant/base.rb', line 132

def translate(&block)
  @translator = Distant::Translator.new
  translator.instance_eval(&block)
end

#translatorObject



128
129
130
# File 'lib/distant/base.rb', line 128

def translator
  @translator
end