Module: Distant::Base::ClassMethods

Defined in:
lib/distant/base.rb

Instance Method Summary collapse

Instance Method Details

#belongs_to(singular, route) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/distant/base.rb', line 77

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 = 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

#belongs_to_relsObject



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

def belongs_to_rels
  @belongs_to
end

#connectionObject



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

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

#get(name, route) ⇒ Object



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

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



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/distant/base.rb', line 65

def has_many(plural, route)
  @has_many << plural.to_sym
  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

#has_many_relsObject



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

def has_many_rels
  @has_many
end

#init_class_varsObject



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

def init_class_vars
  @has_many = [ ]
  @belongs_to = [ ]
end

#marshal(data) ⇒ Object



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

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

#path_closure_generator(route) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/distant/base.rb', line 91

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



108
109
110
111
112
113
114
115
116
117
118
# File 'lib/distant/base.rb', line 108

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



124
125
126
127
# File 'lib/distant/base.rb', line 124

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

#translatorObject



120
121
122
# File 'lib/distant/base.rb', line 120

def translator
  @translator
end