Module: Distant::Base::ClassMethods

Defined in:
lib/distant/base.rb

Instance Method Summary collapse

Instance Method Details

#belongs_to(singular, route) ⇒ Object



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

def belongs_to(singular, route)
  define_method(singular) do
    foreign_key_attr = singular.to_s + '_id'
    foreign_key_value = self.send(foreign_key_attr)
    path = self.class.path_closure_generator(route).call(id: foreign_key_value)
    headers = Distant.config.default_headers('')
                .merge(Distant.config.auth_headers(''))
    response_data = self.class.preprocess_response connection.get(path, headers)
    class_ref = Kernel.const_get self.class.to_s.deconstantize + '::' + singular.to_s.classify
    class_ref.marshal(response_data)
  end
end

#connectionObject



21
22
23
# File 'lib/distant/base.rb', line 21

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

#get(name, route) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/distant/base.rb', line 29

def get(name, route)
  define_singleton_method(name) do |*args|
    path = path_closure_generator(route).call(*args)
    headers = Distant.config.default_headers('')
                .merge(Distant.config.auth_headers(''))
    response_data = preprocess_response connection.get(path, 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



43
44
45
46
47
48
49
50
51
52
# File 'lib/distant/base.rb', line 43

def has_many(plural, route)
  define_method(plural) do
    path = self.class.path_closure_generator(route).call(id: self.id)
    headers = Distant.config.default_headers('')
                .merge(Distant.config.auth_headers(''))
    response_data = self.class.preprocess_response connection.get(path, headers)
    class_ref = Kernel.const_get self.class.to_s.deconstantize + '::' + plural.to_s.singularize.classify
    response_data.map{ |item| class_ref.marshal(item) }
  end
end

#marshal(data) ⇒ Object



25
26
27
# File 'lib/distant/base.rb', line 25

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

#path_closure_generator(route) ⇒ Object



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

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}
  class_eval <<-EOF
    Proc.new do |#{captures.map{|cap| "#{cap}:"}.join(', ')}|
      template % {
        #{captures.map{ |cap| cap + ": " + cap }.join(', ')}
      }
    end
  EOF
end

#preprocess_response(response) ⇒ Object



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

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(item)
  else
    raise Distant::ApiError.new response
  end
end

#translate(&block) ⇒ Object



100
101
102
103
# File 'lib/distant/base.rb', line 100

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

#translatorObject



96
97
98
# File 'lib/distant/base.rb', line 96

def translator
  @translator
end