Class: ActivePodio::Base

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Callbacks, ActiveModel::Naming
Includes:
ActiveModel::Conversion
Defined in:
lib/podio/active_podio/base.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = {}, options = {}) ⇒ Base

Returns a new instance of Base.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/podio/active_podio/base.rb', line 13

def initialize(attributes = {}, options = {})
  self.valid_attributes ||= []
  attributes ||= {}
  self.attributes = Hash[*self.valid_attributes.collect { |n| [n.to_sym, nil] }.flatten].merge(attributes.symbolize_keys)

  @values_from_api = options[:values_from_api] # Used to determine if date times should be converted from local to utc, or are already utc
  
  attributes.each do |key, value|
    if self.respond_to?("#{key}=".to_sym)
      self.send("#{key}=".to_sym, value)
    else
      is_association_hash = value.is_a?(Hash) && self.associations.present? && self.associations.has_key?(key.to_sym) && self.associations[key.to_sym] == :has_one && self.send(key.to_sym).respond_to?(:attributes)
      if valid_attributes.include?(key.to_sym) || is_association_hash
        # Initialize nested object to get correctly casted values set back, unless the given values are all blank
        if is_association_hash
          attributes = self.send(key.to_sym).attributes
          if any_values_present_recursive?(attributes.values)
            value = attributes
          else
            value = nil
          end
        end
        self.send(:[]=, key.to_sym, value)
      end
    end
  end

  @belongs_to = options[:belongs_to] # Allows has_one associations to communicate their changed content back to their parent model
  @values_from_api = false
end

Instance Attribute Details

#attributesObject

Returns the value of attribute attributes.



10
11
12
# File 'lib/podio/active_podio/base.rb', line 10

def attributes
  @attributes
end

#error_codeObject

Returns the value of attribute error_code.



10
11
12
# File 'lib/podio/active_podio/base.rb', line 10

def error_code
  @error_code
end

#error_messageObject

Returns the value of attribute error_message.



10
11
12
# File 'lib/podio/active_podio/base.rb', line 10

def error_message
  @error_message
end

#error_parametersObject

Returns the value of attribute error_parameters.



10
11
12
# File 'lib/podio/active_podio/base.rb', line 10

def error_parameters
  @error_parameters
end

#error_propagateObject Also known as: propagate_error?

Returns the value of attribute error_propagate.



10
11
12
# File 'lib/podio/active_podio/base.rb', line 10

def error_propagate
  @error_propagate
end

Class Method Details

.collection(response) ⇒ Object

Returns a struct that includes:

  • all: A collection model instances

  • count: The number of returned records

  • total_count: The total number of records matching the given conditions



196
197
198
199
200
# File 'lib/podio/active_podio/base.rb', line 196

def collection(response)
  result = Struct.new(:all, :count, :total_count).new(response['items'], response['filtered'], response['total'])
  result.all.map! { |item| new(item, :values_from_api => true) }
  result
end

.delegate_to_hash(hash_name, *attribute_names) ⇒ Object



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/podio/active_podio/base.rb', line 202

def delegate_to_hash(hash_name, *attribute_names)
  options = attribute_names.extract_options!
  options.reverse_merge!(:prefix => false, :setter => false)
  options.assert_valid_keys(:prefix, :setter)
  attribute_names.each do |attribute_name|
    hash_index = attribute_name.to_s.gsub(/[\?!]/, '')
    method_name = "#{options[:prefix] ? "#{hash_name}_" : ''}#{attribute_name}"
    self.send(:define_method, method_name) do
      self.send("#{hash_name}=", {}) unless self.send(hash_name)
      self.send(hash_name)[hash_index]
    end
    if options[:setter]
      self.send(:define_method, "#{method_name}=") do |value|
        self.send("#{hash_name}=", {}) unless self.send(hash_name)
        self.send(hash_name)[hash_index] = value
      end
    end
  end
end

.handle_api_errors_for(*method_names) ⇒ Object

Wraps the given methods in a begin/rescue block If no error occurs, the return value of the method, or true if nil is returned, is returned If a Podio::PodioError occurs, the method returns false and the error can be read from the error_message accessor If another error occurs, it is still raised



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/podio/active_podio/base.rb', line 226

def handle_api_errors_for(*method_names)
  method_names.each do |method_name|
    self.send(:define_method, "#{method_name}_with_api_errors_handled") do |*args|
      success, code, message, parameters, result = nil
      begin
        result = self.send("#{method_name}_without_api_errors_handled", *args)
        success = true
      rescue Podio::PodioError => ex
        success = false
        code        = ex.response_body["error"]
        message     = ex.response_body["error_description"]
        parameters  = ex.response_body["error_parameters"]
        propagate  = ex.response_body["error_propagate"]
      end
    
      if success
        return result || true
      else
        @error_code       = code
        @error_message    = message
        @error_parameters = parameters || {}
        @error_propagate  = propagate
        return false
      end
    end
  
    alias_method_chain method_name, :api_errors_handled
  end
end

.has_many(name, options = {}) ⇒ Object

Wraps a collection of hashes from the API to a collection of the given model



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/podio/active_podio/base.rb', line 157

def has_many(name, options = {})
  self.associations ||= {}
  self.associations[name] = :has_many

  self.send(:define_method, name) do
    klass = klass_for_association(options)
    instances = self.instance_variable_get("@#{name}_has_many_instances")
    unless instances.present?
      property = options[:property] || name.to_sym
      if self[property].present?
        instances = self[property].map { |attributes| klass.new(attributes) }
        self.instance_variable_set("@#{name}_has_many_instances", instances)
      else
        instances = []
      end
    end
    instances
  end
    
  self.send(:define_method, "#{name}?") do
    self.send(name).length > 0
  end
end

.has_one(name, options = {}) ⇒ Object

Wraps a single hash provided from the API in the given model



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/podio/active_podio/base.rb', line 136

def has_one(name, options = {})
  self.associations ||= {}
  self.associations[name] = :has_one

  self.send(:define_method, name) do
    klass = klass_for_association(options)
    instance = self.instance_variable_get("@#{name}_has_one_instance")
    unless instance.present?
      property = options[:property] || name.to_sym
      if self[property].present?
        instance = klass.new(self[property], :belongs_to => { :model => self, :as => property })
        self.instance_variable_set("@#{name}_has_one_instance", instance)
      else
        instance = nil
      end
    end
    instance
  end
end

.list(response) ⇒ Object

Returns a simple collection model instances



187
188
189
190
# File 'lib/podio/active_podio/base.rb', line 187

def list(response)
  response.map! { |item| new(item, :values_from_api => true) }
  response
end

.member(response) ⇒ Object

Returns a single instance of the model



182
183
184
# File 'lib/podio/active_podio/base.rb', line 182

def member(response)
  new(response, :values_from_api => true)
end

.property(name, type = :string, options = {}) ⇒ Object

Defines the the supported attributes of the model



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/podio/active_podio/base.rb', line 114

def property(name, type = :string, options = {})
  self.valid_attributes ||= []
  self.valid_attributes << name
    
  case type
  when :datetime
    define_datetime_accessor(name, options)
  when :date
    define_date_accessor(name)
  when :integer
    define_integer_accessor(name)
  when :boolean
    define_generic_accessor(name, :setter => false)
    define_boolean_accessors(name)
  when :array
    define_array_accessors(name)
  else
    define_generic_accessor(name)
  end
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



72
73
74
# File 'lib/podio/active_podio/base.rb', line 72

def ==(other)
  !self.nil? && !other.nil? && self.respond_to?(:id) && other.respond_to?(:id) && self.id == other.id
end

#[](attribute) ⇒ Object



58
59
60
61
# File 'lib/podio/active_podio/base.rb', line 58

def [](attribute)
  @attributes ||= {}
  @attributes[attribute.to_sym]
end

#[]=(attribute, value) ⇒ Object



63
64
65
66
67
68
69
70
# File 'lib/podio/active_podio/base.rb', line 63

def []=(attribute, value)
  @attributes ||= {}
  @attributes[attribute.to_sym] = value
  if @belongs_to.present? && value.present?
    @belongs_to[:model][@belongs_to[:as]] ||= {}
    @belongs_to[:model][@belongs_to[:as]][attribute.to_sym] = value
  end
end

#as_json(options = {}) ⇒ Object



81
82
83
# File 'lib/podio/active_podio/base.rb', line 81

def as_json(options={})
  self.attributes
end

#hashObject



77
78
79
# File 'lib/podio/active_podio/base.rb', line 77

def hash
  self.id.hash if self.respond_to?(:id)
end

#new_record?Boolean

Returns:

  • (Boolean)


48
49
50
# File 'lib/podio/active_podio/base.rb', line 48

def new_record?
  ! (self.respond_to?(:id) && self.id.present?)
end

#persisted?Boolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/podio/active_podio/base.rb', line 44

def persisted?
  ! self.new_record?
end

#to_paramObject



52
53
54
55
56
# File 'lib/podio/active_podio/base.rb', line 52

def to_param
  local_id = self.id if self.respond_to?(:id)
  local_id = nil if local_id == self.object_id # Id still returns object_id in Ruby 1.8.7, JRuby and Rubinius
  local_id.try(:to_s)
end