Class: Octobat::OctobatObject

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/octobat/octobat_object.rb

Direct Known Subclasses

APIResource, ListObject

Constant Summary collapse

@@permanent_attributes =
Set.new([:api_key, :id])

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id = nil, opts = {}) ⇒ OctobatObject

Returns a new instance of OctobatObject.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/octobat/octobat_object.rb', line 13

def initialize(id=nil, opts={})
  # parameter overloading!
  if id.kind_of?(Hash)
    @retrieve_options = id.dup
    @retrieve_options.delete(:id)
    id = id[:id]
  else
    @retrieve_options = {}
  end
  
  @headers = {}
  @api_key = opts[:api_key]
  
  @retrieve_options.merge!(opts.clone).delete(:api_key)
  @headers['Octobat-Version'] = @retrieve_options.delete('Octobat-Version') if @retrieve_options.has_key?('Octobat-Version')
  
  @values = {}
  # This really belongs in APIResource, but not putting it there allows us
  # to have a unified inspect method
  @unsaved_values = Set.new
  @transient_values = Set.new
  @values[:id] = id if id
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object (protected)



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/octobat/octobat_object.rb', line 174

def method_missing(name, *args)
  # TODO: only allow setting in updateable classes.
  if name.to_s.end_with?('=')
    attr = name.to_s[0...-1].to_sym
    add_accessors([attr])
    begin
      mth = method(name)
    rescue NameError
      raise NoMethodError.new("Cannot set #{attr} on this object. HINT: you can't set: #{@@permanent_attributes.to_a.join(', ')}")
    end
    return mth.call(args[0])
  else
    return @values[name] if @values.has_key?(name)
  end

  begin
    super
  rescue NoMethodError => e
    if @transient_values.include?(name)
      raise NoMethodError.new(e.message + ".  HINT: The '#{name}' attribute was set in the past, however. It was then wiped when refreshing the object with the result returned by Octobat's API, probably as a result of a save().  The attributes currently available on this object are: #{@values.keys.join(', ')}")
    else
      raise
    end
  end
end

Instance Attribute Details

#api_keyObject

Returns the value of attribute api_key.



5
6
7
# File 'lib/octobat/octobat_object.rb', line 5

def api_key
  @api_key
end

#parent_objObject

Returns the value of attribute parent_obj.



5
6
7
# File 'lib/octobat/octobat_object.rb', line 5

def parent_obj
  @parent_obj
end

Class Method Details

._load(args) ⇒ Object



124
125
126
127
# File 'lib/octobat/octobat_object.rb', line 124

def self._load(args)
  values, api_key = Marshal.load(args)
  construct_from(values, api_key)
end

.construct_from(values, api_key = nil) ⇒ Object



37
38
39
# File 'lib/octobat/octobat_object.rb', line 37

def self.construct_from(values, api_key=nil)
  self.new(values[:id], api_key: api_key).refresh_from(values, api_key)
end

Instance Method Details

#[](k) ⇒ Object



85
86
87
# File 'lib/octobat/octobat_object.rb', line 85

def [](k)
  @values[k.to_sym]
end

#[]=(k, v) ⇒ Object



89
90
91
# File 'lib/octobat/octobat_object.rb', line 89

def []=(k, v)
  send(:"#{k}=", v)
end

#_dump(level) ⇒ Object



120
121
122
# File 'lib/octobat/octobat_object.rb', line 120

def _dump(level)
  Marshal.dump([@values, @api_key])
end

#as_json(*a) ⇒ Object



105
106
107
# File 'lib/octobat/octobat_object.rb', line 105

def as_json(*a)
  @values.as_json(*a)
end

#each(&blk) ⇒ Object



116
117
118
# File 'lib/octobat/octobat_object.rb', line 116

def each(&blk)
  @values.each(&blk)
end

#inspectObject



45
46
47
48
# File 'lib/octobat/octobat_object.rb', line 45

def inspect
  id_string = (self.respond_to?(:id) && !self.id.nil?) ? " id=#{self.id}" : ""
  "#<#{self.class}:0x#{self.object_id.to_s(16)}#{id_string}> JSON: " + JSON.pretty_generate(@values)
end

#keysObject



93
94
95
# File 'lib/octobat/octobat_object.rb', line 93

def keys
  @values.keys
end

#refresh_from(values, api_key, partial = false) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/octobat/octobat_object.rb', line 50

def refresh_from(values, api_key, partial=false)
  @api_key = api_key

  @previous_metadata = values[:metadata]
  removed = partial ? Set.new : Set.new(@values.keys - values.keys)
  added = Set.new(values.keys - @values.keys)
  # Wipe old state before setting new.  This is useful for e.g. updating a
  # customer, where there is no persistent card parameter.  Mark those values
  # which don't persist as transient

  #instance_eval do
  remove_accessors(removed)
  add_accessors(added)
  #end
  
  removed.each do |k|
    @values.delete(k)
    @transient_values.add(k)
    @unsaved_values.delete(k)
  end
  values.each do |k, v|
    @values[k] = Util.convert_to_octobat_object(v, api_key)
    
    case @values[k]
    when ListObject
      @values[k].parent_resource = {self.object.to_sym => self.id}
    end
    
    @transient_values.delete(k)
    @unsaved_values.delete(k)
  end

  return self
end

#respond_to?(symbol) ⇒ Boolean

Returns:

  • (Boolean)


130
131
132
# File 'lib/octobat/octobat_object.rb', line 130

def respond_to?(symbol)
  @values.has_key?(symbol) || super
end

#to_hashObject



109
110
111
112
113
114
# File 'lib/octobat/octobat_object.rb', line 109

def to_hash
  @values.inject({}) do |acc, (key, value)|
    acc[key] = value.respond_to?(:to_hash) ? value.to_hash : value
    acc
  end
end

#to_json(*a) ⇒ Object



101
102
103
# File 'lib/octobat/octobat_object.rb', line 101

def to_json(*a)
  JSON.generate(@values)
end

#to_s(*args) ⇒ Object



41
42
43
# File 'lib/octobat/octobat_object.rb', line 41

def to_s(*args)
  JSON.pretty_generate(@values)
end

#valuesObject



97
98
99
# File 'lib/octobat/octobat_object.rb', line 97

def values
  @values.values
end