Class: ActsAsIcontact::Resource

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

Overview

Base class for shared functionality between iContact resources. Supports getting, finding, saving, all that fun stuff.

Direct Known Subclasses

Account, Client, Contact, CustomField, List, Message, Subscription

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(properties = {}) ⇒ Resource

Creates a new resource object from a values hash. (Which is passed to us via the magic of JSON.)



10
11
12
13
14
15
# File 'lib/acts_as_icontact/resource.rb', line 10

def initialize(properties={})
  @properties = clean_properties(properties)
  @new_record = !@properties.has_key?(self.class.primary_key)
  # Initialize other useful attributes
  @errors = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *params) ⇒ Object

Enables keys from the iContact resource to act as attribute methods.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/acts_as_icontact/resource.rb', line 30

def method_missing(method, *params)
  property = method.to_s
  if property =~ /(.*)=$/  # It's a value assignment
    @newvalues ||= []
    @newvalues << $1
    @properties[$1] = clean_value(params[0])
   else
    if @properties.has_key?(property)
      if self.class.boolean_fields.include?(property)
        (@properties[property] == 1)
      else
        @properties[property]
      end
    else
      super
    end
  end
end

Class Method Details

.all(options = {}) ⇒ Object

Returns an array of resources starting at the base.



122
123
124
125
126
127
# File 'lib/acts_as_icontact/resource.rb', line 122

def self.all(options={})
  query_options = default_options.merge(options)
  validate_options(query_options)
  result = query_collection(query_options)
  ResourceCollection.new(self, result)
end

.find(type, options = {}) ⇒ Object

Returns a resource or collection of resources.



106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/acts_as_icontact/resource.rb', line 106

def self.find(type, options={})
  case type
  when :first
    first(options)
  when :all
    all(options)
  when Integer
    find_by_id(type)
  when String
    find_by_string(type)  # Implemented in subclasses
  else
    raise ActsAsIcontact::QueryError, "Don't know how to find '#{type.to_s}'"
  end
end

.find_by_id(id) ⇒ Object

Returns the single resource at the URL identified by the passed integer. Takes no options; this is not a search, this is a single record retrieval. Raises an exception if the record can’t be found.



139
140
141
142
143
144
145
146
# File 'lib/acts_as_icontact/resource.rb', line 139

def self.find_by_id(id)
  response = self.connection[id].get
  parsed = JSON.parse(response)
  raise ActsAsIcontact::QueryError, "iContact's response did not contain a #{resource_name}!" unless parsed[resource_name]
  self.new(parsed[resource_name])
rescue RestClient::ResourceNotFound
  raise ActsAsIcontact::QueryError, "The #{resource_name} with id #{id} could not be found"
end

.first(options = {}) ⇒ Object

Returns the first account associated with this username.



130
131
132
133
134
135
# File 'lib/acts_as_icontact/resource.rb', line 130

def self.first(options={})
  query_options = default_options.merge(options).merge(:limit => 1) # Minor optimization
  validate_options(query_options)
  result = query_collection(query_options)
  self.new(result[collection_name].first)
end

Instance Method Details

#==(obj) ⇒ Object

Two resources are identical if they have exactly the same property array.



149
150
151
# File 'lib/acts_as_icontact/resource.rb', line 149

def ==(obj)
  properties == obj.properties
end

#connectionObject

Returns the specific RestClient connection for an existing resource. (E.g., the connection to “api.icontact.com/icp/a/12345” for account 12345.) Returns nil if the resource is a new record.



25
26
27
# File 'lib/acts_as_icontact/resource.rb', line 25

def connection
  self.class.connection[id] unless new_record?
end

#errorObject

The first message from the errors array.



96
97
98
# File 'lib/acts_as_icontact/resource.rb', line 96

def error
  errors.first
end

#errorsObject

The warning messages sent back by iContact on a failed request.



101
102
103
# File 'lib/acts_as_icontact/resource.rb', line 101

def errors
  @errors
end

#idObject

Returns the primary key ID for an existing resource. Returns nil if the resource is a new record.



18
19
20
# File 'lib/acts_as_icontact/resource.rb', line 18

def id
  @properties[self.class.primary_key].to_i unless new_record?
end

#new_record?Boolean

Returns true if the resource object did not originate from iContact. We determine this by the rather naive method of checking upon creation whether one of the properties passed was the primary key.

Returns:

  • (Boolean)


52
53
54
# File 'lib/acts_as_icontact/resource.rb', line 52

def new_record?
  @new_record
end

#saveObject

Sends changes to iContact. Returns true if the save was successful (i.e. we receive an updated object back from them); if it was not, returns false and populates the errors array with the warnings iContact sends to us. If iContact returns an HTTP error, raises an exception with it.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/acts_as_icontact/resource.rb', line 60

def save
  if new_record?
    fields = create_fields
    validate_on_create(fields)
    result_type = self.class.collection_name
    response = self.class.connection.post([fields].to_json)
  else
    fields = update_fields
    validate_on_update(fields)
    result_type = self.class.resource_name
    response = connection.post(fields.to_json)
  end
  parsed = JSON.parse(response)
  if parsed[result_type].empty?
    @errors = parsed["warnings"] || []
    false
  else
    @properties = (new_record? ? parsed[result_type].first : parsed[result_type])
    @new_record = false
    @errors = []
    true
  end 
rescue RestClient::RequestFailed => e
  response = e.response.body
  parsed = JSON.parse(response)
  @errors = parsed["errors"] || [e.message]
  false
end

#save!Object

Like save, but raises an ActsAsIcontact::RecordNotSaved exception if the save failed. The exception message contains the first error from iContact.



91
92
93
# File 'lib/acts_as_icontact/resource.rb', line 91

def save!
  save or raise ActsAsIcontact::RecordNotSaved.new(errors)
end