class Geocode < ActiveRecord::Base cattr_accessor :api_key self.api_key = "http://www.google.com/apis/maps/signup.html" belongs_to :geocodable, :polymorphic => true serialize :addresses, Array validates_presence_of :geocodable_id, :geocodable_type, :addresses def addresses=(value) value = [*value] unless value.is_a?(Array) if value != self.addresses self.attributes = { :latitude => nil, :longitude => nil, :accuracy => nil, :geocoded_address => nil, :geocoding_result => nil } end write_attribute(:addresses, value) end def to_location unless latitude.blank? or longitude.blank? GoogleGeocode::Location.new(latitude, longitude, geocoded_address, accuracy) end end class << self def populate geocoder = GoogleGeocode.new(api_key) transaction do find(:all, :conditions => { :geocoding_result => nil }).each do |geocode| geocode.addresses.each do |address| begin geocode.last_attempted_at = Time.now location = geocoder.locate(address) result = false if location.accuracy == 8 geocode.attributes = { :latitude => location.latitude, :longitude => location.longitude, :accuracy => location.accuracy, :geocoded_address => location.address, :geocoding_result => 'Success' } result = true else geocode.geocoding_result = 'Inaccurate' end rescue GoogleGeocode::AddressError => e geocode.geocoding_result = e.message.humanize rescue => e geocode.geocoding_result = e.message end logger.info "\nGeocoding:\n Address: #{address}\n Result: #{geocode.geocoding_result}\n" break if result end geocode.save! end end end def find_unsuccessful find(:all, :conditions => "geocoding_result <> 'Success'") end end end