class RightApi::ResourceDetail

Takes the information returned from the API and converts it into instance methods

Attributes

actions[R]
associations[R]
attributes[R]
client[R]
raw[R]
resource_type[R]

Public Class Methods

new(client, resource_type, href, hash) click to toggle source

ResourceDetail will MODIFY hash

# File lib/right_api_client/resource_detail.rb, line 15
def initialize(client, resource_type, href, hash)
  @client = client
  @resource_type = resource_type
  @raw = hash.dup
  @attributes, @associations, @actions = Set.new, Set.new, Set.new
  @attributes_with_values = {}

  links = hash.delete('links') || []
  raw_actions = hash.delete('actions') || []

  # We have to delete the self href from the links because later we will
  # go through these links and add them in as methods
  self_hash = get_and_delete_href_from_links(links)
  if self_hash != nil
    hash['href'] = self_hash
  end

  # Add links to attributes set and create a method that returns the links
  attributes << :links
  define_instance_method(:links) { return links }

  # Follow the actions:
    # API doesn't tell us whether a resource action is a GET or a POST, but
    # they are all post so add them all as posts for now.
  raw_actions.each do |action|
    action_name = action['rel']
    # Add it to the actions set
    actions << action_name.to_sym

    define_instance_method(action_name.to_sym) do |*args|
      client.send(:do_post, "#{hash['href']}/#{action['rel']}", *args)
    end
  end

  # Follow the links to create methods
  get_associated_resources(client, links, associations)

  # Some resources are not linked together, so they have to be manually
  # added here.
  case resource_type
  when 'instance'
    define_instance_method('live_tasks') do |*args|
      if has_id(*args)
        path = href + '/live/tasks'
        path = add_id_and_params_to_path(path, *args)
        RightApi::Resource.process(client, 'live_task', path)
      end
    end
  end

  # Add the rest as instance methods
  hash.each do |k, v|
    k = k.to_sym
    # If a parent resource is requested with a view then it might return
    # extra data that can be used to build child resources here, without
    # doing another get request.
    if associations.include?(k)
      # v might be an array or hash so use include rather than has_key
      if v.include?('links')
        child_self_link = v['links'].find { |target| target['rel'] == 'self' }
        if child_self_link
          child_href = child_self_link['href']
          if child_href
            # Currently, only instances need this optimization, but in the
            # future we might like to extract resource_type from child_href
            # and not hard-code it.
            if child_href.index('instance')
              define_instance_method(k) do |*args|
                path = add_id_and_params_to_path(child_href, *args)
                RightApi::Resource.process(client, 'instance', path, v)
              end
            end
          end
        end
      else
        # This is an attribute whose name coincides with the name of a link,
        # but which isn't actually an embedded subrecource (it has no links
        # or other media-type decorators). Add it to attributes.
        attributes << k
        @attributes_with_values[k] = v
      end
    else
      # Add it to the attributes set and create a method for it
      attributes << k
      @attributes_with_values[k] = v
      define_instance_method(k) { return @attributes_with_values[k] }
    end
  end

  # Add destroy method to relevant resources
  define_instance_method('destroy') do |*args|
    client.send(:do_delete, href, *args)
  end

  # Add update method to relevant resources
  define_instance_method('update') do |*args|

    if resource_type == 'account' # HACK: handle child_account update specially
      update_href = href.sub(/account/, 'child_account')
      client.send(:do_put, update_href, *args)
    else
      client.send(:do_put, href, *args)
    end
  end

  # Add show method to relevant resources
  define_instance_method('show') do |*args|
    self
  end
end

Public Instance Methods

[](k) click to toggle source

Access attributes of this resource in a Hash-like manner. This is useful in cases where an attribute name coincides with a link name, e.g. a resource that contains embedded subresources.

This method can accept String or Symbol attribute names. The data type of the returned object is unspecified; it could be a String, Integer, Hash, Array or any other JSON data type. If a Hash is returned, then its keys will always be String.

# File lib/right_api_client/resource_detail.rb, line 134
def [](k)
  @attributes_with_values[k.to_sym]
end
inspect() click to toggle source
# File lib/right_api_client/resource_detail.rb, line 7
def inspect
  "#<#{self.class.name} " +
  "resource_type=\"#{@resource_type}\"" +
  "#{', name=' + name.inspect if self.respond_to?(:name)}" +
  "#{', resource_uid='+ resource_uid.inspect if self.respond_to?(:resource_uid)}>"
end
method_missing(m, *args) click to toggle source

Any other method other than standard actions(show,update,destroy) is simply appended to the href and called with a POST.

# File lib/right_api_client/resource_detail.rb, line 140
def method_missing(m, *args)
  # the method href would have been defined while initializing the object
  client.send(:do_post, [ href, m.to_s ].join('/'), *args)
end