Skip to content

Commit

Permalink
refactor to allow for ruby style accessor methods
Browse files Browse the repository at this point in the history
  • Loading branch information
woodhull committed Jan 27, 2011
1 parent 93ef71e commit 34b37a0
Show file tree
Hide file tree
Showing 16 changed files with 124 additions and 45 deletions.
13 changes: 10 additions & 3 deletions README.textile
Expand Up @@ -48,14 +48,21 @@ This library has a specific way to build and read API objects. Each class can t
# Modify the title later
@p["title"] => "My Awesome Campaign"

# or use the ruby style accessor

@p.title = 'My Awesome Campaign'

# Look at all the variables
@p.variables.inspect
=> {"title" => "My Awesome Campaign"}
</pre>

Each API object has 3 constants defined: XML_NAME, ATTRIBUTES and ELEMENTS. The ATTRIBUTES and ELEMENTS reveal the possible variables you can pass into the constructor and modify per the example above. The XML_NAME is used for serializing an API object to XML for delivery back to ActBlue.
# or a specific one.

@p.title.inspect
=> "My Awesome Campaign"
</pre>

The reason a variable hash is exposed with the [] operator and variables are not simply getter/setter instance methods is due to the fact that the ActBlue API has several attributes and elements that have a '-' dash in their name.
Original ActBlue field names are available with the [] operator - this allows access to attributes and elements that have a '-' dash in their name. Ruby equivalents to these names are available as accessor methods with the dashes replaced with underscores.

When creating objects with nested elements you should use the corresponding API objects. For example if I wanted to add some Listentries to the Page object we were working with above:

Expand Down
51 changes: 48 additions & 3 deletions lib/actblue/active_blue.rb
Expand Up @@ -4,7 +4,7 @@ module ActBlue
ACTBLUE_VERSION = "2007-10-1"
ACTBLUE_URL = ENV['ACTBLUE_URL'] || "https://secure.actblue.com"

class ActiveBlue
module ActiveBlue
include HTTParty
format :xml
base_uri "#{ACTBLUE_URL}/#{ACTBLUE_VERSION}"
Expand All @@ -13,6 +13,51 @@ class ActiveBlue

attr_accessor :variables

# add accessors and other class methods places where this has been included

module ClassMethods
def elements
@elements || []
end

def attributes
@attributes || []
end

def add_attributes(attributes)
@attributes = attributes
setup_accessors(attributes)
end

def add_elements(elements)
@elements = elements
setup_accessors(elements)
end

def setup_accessors(names)
accessor_name_hash = { }
names.each do | key |
accessor_name_hash[key.gsub('-', '_')] = key
end

accessor_name_hash.each do | accessor_name, variable_name|
# assignment
define_method "#{accessor_name}=".intern do | value |
@variables[variable_name] = value
end
# access
define_method accessor_name.intern do
@variables[variable_name]
end
end
end

end

def self.included(base)
base.extend ClassMethods
end

def line_items_lambda
lambda do |hash|
if (hash.is_a?(Array) && hash.first.class.name == "ActBlue::LineItem")
Expand Down Expand Up @@ -99,10 +144,10 @@ def to_xml

def to_xml_element
element = REXML::Element.new(self.class::XML_NAME)
self.class::ATTRIBUTES.each do |a|
self.class.attributes.each do |a|
element.add_attribute(a, @variables[a]) if @variables[a]
end
self.class::ELEMENTS.each do |e|
self.class.elements.each do |e|
if @variables[e]
if act_types[e] && act_types[e].is_a?(Proc)
parentElement = REXML::Element.new(e)
Expand Down
7 changes: 4 additions & 3 deletions lib/actblue/candidacy.rb
@@ -1,10 +1,11 @@
module ActBlue

class Candidacy < ActiveBlue
class Candidacy
include ActiveBlue

XML_NAME = 'candidacy'
ATTRIBUTES = ['id']
ELEMENTS = ['election','result']
add_attributes ['id']
add_elements ['election','result']

end

Expand Down
7 changes: 4 additions & 3 deletions lib/actblue/check.rb
@@ -1,10 +1,11 @@
module ActBlue

class Check < ActiveBlue
class Check
include ActiveBlue

XML_NAME = 'check'
ATTRIBUTES = ['id']
ELEMENTS = ['date', 'number']
add_attributes ['id']
add_elements ['date', 'number']

end

Expand Down
7 changes: 4 additions & 3 deletions lib/actblue/contribution.rb
@@ -1,10 +1,11 @@
module ActBlue

class Contribution < ActiveBlue
class Contribution
include ActiveBlue

XML_NAME = 'contribution'
ATTRIBUTES = ['order-number', 'created-on']
ELEMENTS = ['page', 'refcode', 'source', 'timestamp', 'submitter', 'recurring', 'recurringtimes', 'referrer', 'successuri', 'lineitems']
add_attributes ['order-number', 'created-on']
add_elements ['page', 'refcode', 'source', 'timestamp', 'submitter', 'recurring', 'recurringtimes', 'referrer', 'successuri', 'lineitems']

def self.get(params)
hash = ActiveBlue.get('/contributions', :query => params)
Expand Down
6 changes: 3 additions & 3 deletions lib/actblue/credit_card.rb
@@ -1,10 +1,10 @@
module ActBlue

class CreditCard < ActiveBlue
class CreditCard
include ActiveBlue

XML_NAME = 'creditcard'
ATTRIBUTES = []
ELEMENTS = ['name', 'billing-addr1', 'billing-addr2', 'billing-city', 'billing-state', 'billing-postalcode', 'account', 'expires', 'verifier']
add_elements ['name', 'billing-addr1', 'billing-addr2', 'billing-city', 'billing-state', 'billing-postalcode', 'account', 'expires', 'verifier']

end

Expand Down
7 changes: 4 additions & 3 deletions lib/actblue/election.rb
@@ -1,10 +1,11 @@
module ActBlue

class Election < ActiveBlue
class Election
include ActiveBlue

XML_NAME = 'election'
ATTRIBUTES = ['id']
ELEMENTS = ['election_date','office']
add_attributes ['id']
add_elements ['election_date','office']

end

Expand Down
7 changes: 4 additions & 3 deletions lib/actblue/entity.rb
@@ -1,10 +1,11 @@
module ActBlue

class Entity < ActiveBlue
class Entity
include ActiveBlue

XML_NAME = 'entity'
ATTRIBUTES = ['id']
ELEMENTS = ['legalname', 'displayname', 'sortname', 'jurisdiction', 'govid', 'prefacewiththe', 'donate', 'kind', 'state', 'party', 'url', 'visible','candidacy']
add_attributes ['id']
add_elements ['legalname', 'displayname', 'sortname', 'jurisdiction', 'govid', 'prefacewiththe', 'donate', 'kind', 'state', 'party', 'url', 'visible','candidacy']

end

Expand Down
6 changes: 3 additions & 3 deletions lib/actblue/expires.rb
@@ -1,10 +1,10 @@
module ActBlue

class Expires < ActiveBlue
class Expires
include ActiveBlue

XML_NAME = 'expires'
ATTRIBUTES = ['year', 'month']
ELEMENTS = []
add_attributes ['year', 'month']

end

Expand Down
6 changes: 3 additions & 3 deletions lib/actblue/instrument.rb
@@ -1,10 +1,10 @@
module ActBlue

class Instrument < ActiveBlue
class Instrument
include ActiveBlue

XML_NAME = 'instrument'
ATTRIBUTES = []
ELEMENTS = ['creditcard', 'check']
add_elements ['creditcard', 'check']

end

Expand Down
7 changes: 4 additions & 3 deletions lib/actblue/line_item.rb
@@ -1,10 +1,11 @@
module ActBlue

class LineItem < ActiveBlue
class LineItem
include ActiveBlue

XML_NAME = 'lineitem'
ATTRIBUTES = ['id','effective-at', 'status', 'visibility']
ELEMENTS = ['amount', 'fee', 'entity', 'aq-fee', 'premium-fee', 'processing-fee', 'jurisdiction']
add_attributes ['id','effective-at', 'status', 'visibility']
add_elements ['amount', 'fee', 'entity', 'aq-fee', 'premium-fee', 'processing-fee', 'jurisdiction']

end

Expand Down
7 changes: 4 additions & 3 deletions lib/actblue/list_entry.rb
@@ -1,10 +1,11 @@
module ActBlue

class ListEntry < ActiveBlue
class ListEntry
include ActiveBlue

XML_NAME = 'listentry'
ATTRIBUTES = ['page','entity','position']
ELEMENTS = ['blurb']
add_attributes ['page','entity','position']
add_elements ['blurb']

end

Expand Down
7 changes: 4 additions & 3 deletions lib/actblue/office.rb
@@ -1,10 +1,11 @@
module ActBlue

class Office < ActiveBlue
class Office
include ActiveBlue

XML_NAME = 'office'
ATTRIBUTES = ['id']
ELEMENTS = ['name','description','race_type','district','seat_count','state']
add_attributes ['id']
add_elements ['name','description','race_type','district','seat_count','state']

end

Expand Down
7 changes: 4 additions & 3 deletions lib/actblue/page.rb
@@ -1,10 +1,11 @@
module ActBlue

class Page < ActiveBlue
class Page
include ActiveBlue

XML_NAME = 'page'
ATTRIBUTES = ['name', 'partner', 'created-on']
ELEMENTS = ['title', 'author', 'blurb', 'visibility', 'showcandidatesummary', 'listentries']
add_attributes ['name', 'partner', 'created-on']
add_elements ['title', 'author', 'blurb', 'visibility', 'showcandidatesummary', 'listentries']

def post
ActiveBlue.post('/pages', :body => to_xml)
Expand Down
6 changes: 3 additions & 3 deletions lib/actblue/source.rb
@@ -1,10 +1,10 @@
module ActBlue

class Source < ActiveBlue
class Source
include ActiveBlue

XML_NAME = 'source'
ATTRIBUTES = []
ELEMENTS = ['firstname', 'lastname', 'addr1', 'addr2', 'city', 'state', 'zip', 'country', 'employer', 'occupation', 'empaddr1', 'empaddr2', 'empcity', 'empstate', 'empzip', 'empcountry', 'email', 'phone']
add_elements ['firstname', 'lastname', 'addr1', 'addr2', 'city', 'state', 'zip', 'country', 'employer', 'occupation', 'empaddr1', 'empaddr2', 'empcity', 'empstate', 'empzip', 'empcountry', 'email', 'phone']

end

Expand Down
18 changes: 18 additions & 0 deletions spec/page_spec.rb
Expand Up @@ -33,6 +33,24 @@
end
end

describe "accessors" do
it "should have basic accessors" do
page = Page.new(:title => "test title", "listentries" => {"listentry" => [{:blurb => "body one"}, {:blurb => "body two"}]})
page.title.should == 'test title'
page.title = 'another title'
page.title.should == 'another title'
page['title'].should == 'another title'
end

it "should autotransform accessors with dashes" do
t = Time.now
page = Page.new('created-on' => t, :title => "test title", "listentries" => {"listentry" => [{:blurb => "body one"}, {:blurb => "body two"}]})
page.created_on.should == t
page.created_on = 'foo'
page['created-on'].should == 'foo'
end
end

describe "#to_xml" do
it "should describe the contribution in xml" do
page = ActBlue::Page.new('name' => 'a', 'title' => 'b')
Expand Down

0 comments on commit 34b37a0

Please sign in to comment.