Class: Swivel::Response

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

Overview

Encapsulates XML that Swivel returns from an API call. Generally, you’ll never need to instantiate a Swivel::Response object. Use one of its subclasses instead:

  • Swivel::List

  • Classes defined with metaprogrammatically (and so unseen in rdoc)

    • Swivel::DataSet

    • Swivel::DataColumn

    • Swivel::Graph

    • Swivel::User

    • others

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(xml, connection, hashdoc) ⇒ Response

Instantiate from XML returned from Swivel.



145
146
147
148
149
150
151
152
153
154
# File 'lib/swivel.rb', line 145

def initialize xml, connection, hashdoc
  raise 'invalid arguments, either xml or hashdoc needs to be passed in' if hashdoc.nil? && xml.nil?
  @connection = connection
  @disable_auto_refresh = @connection && @connection.disable_auto_refresh
  @xml_tag = self.class.name.demodulize.to_xml_tag
  @hash_doc = hashdoc
  @hash_doc ||= CobraVsMongoose.xml_to_hash xml
  @hash_doc = @hash_doc['response'] if @hash_doc.is_a?(Hash) && @hash_doc['response']
  @hash_doc = @hash_doc[self.class.resource] if @hash_doc.is_a?(Hash) && @hash_doc[self.class.resource]
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_id) ⇒ Object

Most of the work in processing responses from Swivel happens here. It’s pretty flexible in what it returns:

  • text from attributes

    data_set = swivel.call '/data_sets/1005309'
    data_set.to_xml # => "<data-set swivel-id=\"1005309\"> ..."
    
    # invokes method_missing
    data_set.id # => 1005309
    
  • text from elements

    data_set = swivel.call '/data_sets/1005309'
    data_set.to_xml # => "<data-set ...><name>Swivel API</name> ..."
    
    # invokes method_missing
    data_set.name # => "Swivel API"
    
  • objects that inherit from Swivel::Response (including Swivel::List)

    data_set = swivel.call '/data_sets/1005309'
    data_set.to_xml # => "<data-set ...><user swivel-id=\"1000010\"> ..."
    
    # invokes method_missing
    data_set.user.class # => Swivel::User
    


178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/swivel.rb', line 178

def method_missing method_id
  method_name = method_id.to_s.singularize.to_xml_tag
  list_name = method_id.to_s.to_xml_tag
  
  # 1)look in attributes
  # 2)look in elements
  #   2a) if value return it
  #   2b) if hash return an obj
  #   2c) if method_name.pluralize, return a list
  # 3)look in lists
  
  if @hash_doc["@#{method_name}"]
    value_for @hash_doc["@#{method_name}"]
  elsif @hash_doc[method_name]
    if @hash_doc[method_name].is_a? Hash
      if @hash_doc[method_name].has_key?('$')
        value_for @hash_doc[method_name]['$']
      elsif @hash_doc[method_name].size == 1 and @hash_doc[method_name].has_key? '@type'
        nil
      elsif @hash_doc[method_name].blank?
        nil
      else
        Response.class_for(method_name).new(nil, @connection, @hash_doc[method_name])
      end
    else
      value_for @hash_doc[method_name]
    end
    
  # 2c) from above - enables rails ActiveRecord::Base#to_xml style lists
  elsif @hash_doc[list_name].is_a? Hash and
      @hash_doc[list_name]['@type'] == 'array'
    member_name = (@hash_doc[list_name].keys.find{|k| !/^@/.match(k) } || list_name.singularize)
    list = (@hash_doc[list_name][member_name] || [] rescue [])
    list = [list] unless list.is_a?(Array)
    # hack to get the gem to parse all array types correctly
    hack_list = list.map{|i| {member_name => i}}
    Swivel::List.new nil, @connection, hack_list, member_name, list.size, list.size

  elsif @hash_doc['list'] && @hash_doc['list'].is_a?(Hash) && @hash_doc['list']['@resource'] == method_name
    Swivel::List.new nil, @connection, (@hash_doc['list'][method_name].nil? ? [] : @hash_doc['list'][method_name]), method_name, @hash_doc['list']['@count'], @hash_doc['list']['@total']
  elsif @hash_doc['list'] && @hash_doc['list'].is_a?(Array) && @hash_doc['list'].any?{|h| h['@resource'] == method_name}
    list_el = @hash_doc['list'].select{|h| h['@resource'] == method_name}.first
    Swivel::List.new nil, @connection,(list_el[method_name].nil? ? [] : list_el[method_name]), method_name, list_el['@count'], list_el['@total']
  elsif @hash_doc[method_name.pluralize]
    if @hash_doc[method_name.pluralize].has_key?('$')
      value_for @hash_doc[method_name.pluralize]['$'] 
    else
      @hash_doc[method_name.pluralize]
    end
  else 
    raise NoMethodError, "#{method_id} isn't a method of #{self.class.name}"
  end
rescue Exception => e
  if @disable_auto_refresh || @retried || @refreshed_at
    nil
  else
    @retried = true
#        refresh! true
    retry
  end
end

Instance Attribute Details

#disable_auto_refreshObject

Returns the value of attribute disable_auto_refresh.



138
139
140
# File 'lib/swivel.rb', line 138

def disable_auto_refresh
  @disable_auto_refresh
end

#hash_docObject

Returns the value of attribute hash_doc.



138
139
140
# File 'lib/swivel.rb', line 138

def hash_doc
  @hash_doc
end

#refreshed_atObject

Returns the value of attribute refreshed_at.



138
139
140
# File 'lib/swivel.rb', line 138

def refreshed_at
  @refreshed_at
end

Class Method Details

.resourceObject



140
141
142
# File 'lib/swivel.rb', line 140

def self.resource
  nil
end

Instance Method Details

#[](attribute) ⇒ Object

Alternate access to properties. Same as dot notation, so user == user.name



242
243
244
245
246
247
248
249
# File 'lib/swivel.rb', line 242

def [](attribute)
  case attribute
  when Symbol, String
    self.send(attribute)
  else
    super
  end
end

#idObject

Returns the unique id in swivel for this object. Ids are unique for each resource.

user = swivel.call '/users/1000010'
user.id # => 1000010
user.id == user.swivel_id # => true


257
258
259
# File 'lib/swivel.rb', line 257

def id
  method_missing(:id) or swivel_id
end

#to_paramObject

Same as id method, added to make Swivel objects play well with url_for in Rails.



264
265
266
# File 'lib/swivel.rb', line 264

def to_param
  id.to_s
end

#to_sObject

Try to be somewhat useful about to_s. Maybe not great.



295
296
297
# File 'lib/swivel.rb', line 295

def to_s
  self.class.name.demodulize + ' ' + (name || title || inspect)
end

#to_xmlObject

Returns the underlying XML string for this object as a string.

user = swivel.call '/users/1000010'
puts user.to_xml


289
290
291
# File 'lib/swivel.rb', line 289

def to_xml
  @doc.to_s
end