From b015a546d6d176fd1a0e51cb8a6950f818f2b466 Mon Sep 17 00:00:00 2001
From: Alex Reisner <alex@alexreisner.com>
Date: Fri, 28 Aug 2009 11:43:41 -0400
Subject: [PATCH] Use geocoded_by method instead of include Geocoder for
 flexibility and cleaner syntax.

---
 README.rdoc     | 13 +++----------
 init.rb         | 12 +++++++++++-
 lib/geocoder.rb | 25 ++++++++++++++-----------
 3 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/README.rdoc b/README.rdoc
index 98c8932f..74d4d5bc 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -13,15 +13,13 @@ Use the Rails plugin install script:
 
 To add geocoding features to a class:
 
-  include Geocoder
+  geocoded_by :location
 
 Be sure your class defines read/write attributes +latitude+ and +longitude+ as
-well as a method called +location+ that returns a string suitable for passing
-to a Google Maps search, for example:
+well as a method called +location+ (or whatever name you pass to +geocoded_by+)
+that returns a string suitable for passing to a Google Maps search, for example:
 
-  New York City
   714 Green St, Big Town, MO
-  Dusseldorf, DE
 
 If your model has +address+, +city+, +state+, and +country+ attributes your
 +location+ method might look something like this:
@@ -52,10 +50,5 @@ within a given distance from a point, this method will generate a query for you:
 Please see the code for more methods and detailed information about arguments.
 
 
-== Todo
-
-* use geocoded_by(:location) instead of hard-coding 'location' method
-  * don't include/extend unless geocoded_by is called
-
   
 Copyright (c) 2009 Alex Reisner, released under the MIT license
diff --git a/init.rb b/init.rb
index 3c19a743..ddd1d172 100644
--- a/init.rb
+++ b/init.rb
@@ -1 +1,11 @@
-# Include hook code here
+ActiveRecord::Base.class_eval do
+  
+  ##
+  # Include the Geocoder module and set the method name which returns
+  # the geo-search string.
+  #
+  def self.geocoded_by(method_name = :location)
+    include Geocoder
+    @geocoder_method_name = method_name
+  end
+end
diff --git a/lib/geocoder.rb b/lib/geocoder.rb
index 61640e6d..6bc5ef52 100644
--- a/lib/geocoder.rb
+++ b/lib/geocoder.rb
@@ -1,8 +1,5 @@
 ##
-# Add geocoding functionality (via Google) to any object that implements
-# a method (+location+ by default) that returns a string suitable for a
-# Google Maps search. The object should also implement reader and writer
-# methods for +latitude+ and +longitude+ attributes.
+# Add geocoding functionality (via Google) to any object.
 #
 module Geocoder
   
@@ -31,9 +28,8 @@ module Geocoder
     doc = self.search(query)
     
     # Make sure search found a result.
-    unless (e = doc.elements['kml/Response/Status/code']) and e.text == "200"
-      return nil
-    end
+    e = doc.elements['kml/Response/Status/code']
+    return nil unless (e and e.text == "200")
     
     # Isolate the relevant part of the result.
     place = doc.elements['kml/Response/Placemark']
@@ -62,6 +58,13 @@ module Geocoder
         latitude, longitude, radius.to_i, options)
       find_by_sql(query)
     end
+    
+    ##
+    # Get the name of the method that returns the search string.
+    #
+    def geocoder_method_name
+      defined?(@geocoder_method_name) ? @geocoder_method_name : :location
+    end
   end
   
   ##
@@ -76,15 +79,15 @@ module Geocoder
   # Fetch coordinates based on the object's object's +location+. Returns an
   # array <tt>[lat,lon]</tt>.
   #
-  def fetch_coordinates(attribute = :location)
-    Geocoder.fetch_coordinates(send(attribute))
+  def fetch_coordinates
+    Geocoder.fetch_coordinates(send(self.class.geocoder_method_name))
   end
   
   ##
   # Fetch and assign +latitude+ and +longitude+.
   #
-  def fetch_and_assign_coordinates(attribute = :location)
-    if c = fetch_coordinates(attribute)
+  def fetch_and_assign_coordinates
+    if c = fetch_coordinates(self.class.geocoder_method_name)
       self.latitude = c[0]
       self.longitude = c[1]
       return c
-- 
GitLab