diff --git a/lib/geocoder.rb b/lib/geocoder.rb index 53e7133ae062fce5ebcde885306a97fd007702a2..2030b787e880812dcc5bb8e414cd6322449f0540 100644 --- a/lib/geocoder.rb +++ b/lib/geocoder.rb @@ -1,6 +1,5 @@ require "geocoder/configuration" require "geocoder/calculations" -require "geocoder/active_record" require "geocoder/railtie" module Geocoder diff --git a/lib/geocoder/active_record.rb b/lib/geocoder/orms/active_record.rb similarity index 73% rename from lib/geocoder/active_record.rb rename to lib/geocoder/orms/active_record.rb index 018140d5bacd6ceaee0bed51e45693464eb16b5c..fe439af9dab1164b0b7eaef08c5607cd05143d7f 100644 --- a/lib/geocoder/active_record.rb +++ b/lib/geocoder/orms/active_record.rb @@ -1,8 +1,11 @@ +require 'geocoder/orms/base' + ## # Add geocoding functionality to any ActiveRecord object. # -module Geocoder +module Geocoder::Orm module ActiveRecord + include Base ## # Implementation of 'included' hook method. @@ -141,73 +144,6 @@ module Geocoder end end - ## - # Read the coordinates [lat,lon] of an object. This is not great but it - # seems cleaner than polluting the instance method namespace. - # - def read_coordinates - [:latitude, :longitude].map{ |i| send self.class.geocoder_options[i] } - end - - ## - # Is this object geocoded? (Does it have latitude and longitude?) - # - def geocoded? - read_coordinates.compact.size > 0 - end - - ## - # Calculate the distance from the object to a point (lat,lon). - # - # <tt>:units</tt> :: <tt>:mi</tt> (default) or <tt>:km</tt> - # - def distance_to(lat, lon, units = :mi) - return nil unless geocoded? - mylat,mylon = read_coordinates - Geocoder::Calculations.distance_between(mylat, mylon, lat, lon, :units => units) - end - - ## - # Get other geocoded objects within a given radius. - # - # <tt>:units</tt> :: <tt>:mi</tt> (default) or <tt>:km</tt> - # - def nearbys(radius = 20, units = :mi) - return [] unless geocoded? - options = {:exclude => self, :units => units} - self.class.near(read_coordinates, radius, options) - end - - ## - # Look up geographic data based on object attributes, - # and do something with it (requires a block). - # - def geocode(reverse = false, &block) - if reverse - lat_attr = self.class.geocoder_options[:latitude] - lon_attr = self.class.geocoder_options[:longitude] - unless lat_attr.is_a?(Symbol) and lon_attr.is_a?(Symbol) - raise Geocoder::ConfigurationError, - "You are attempting to fetch an address but have not specified " + - "attributes which provide coordinates for the object." - end - args = [send(lat_attr), send(lon_attr)] - else - address_method = self.class.geocoder_options[:user_address] - unless address_method.is_a? Symbol - raise Geocoder::ConfigurationError, - "You are attempting to geocode an object but have not specified " + - "a method which provides an address to search for." - end - args = [send(address_method)] - end - # passing a block to this method overrides the one given in the model - b = block_given?? block : self.class.geocoder_options[:block] - if result = Geocoder.search(*args).first - b.call(result) - end - end - ## # Fetch coordinates and assign +latitude+ and +longitude+. Also returns # coordinates as an array: <tt>[lat, lon]</tt>. diff --git a/lib/geocoder/orms/base.rb b/lib/geocoder/orms/base.rb new file mode 100644 index 0000000000000000000000000000000000000000..04d57597d9c4931e2846e4b9f611e2651c331119 --- /dev/null +++ b/lib/geocoder/orms/base.rb @@ -0,0 +1,73 @@ +module Geocoder + module Orm + module Base + + ## + # Read the coordinates [lat,lon] of an object. This is not great but it + # seems cleaner than polluting the instance method namespace. + # + def read_coordinates + [:latitude, :longitude].map{ |i| send self.class.geocoder_options[i] } + end + + ## + # Is this object geocoded? (Does it have latitude and longitude?) + # + def geocoded? + read_coordinates.compact.size > 0 + end + + ## + # Calculate the distance from the object to a point (lat,lon). + # + # <tt>:units</tt> :: <tt>:mi</tt> (default) or <tt>:km</tt> + # + def distance_to(lat, lon, units = :mi) + return nil unless geocoded? + mylat,mylon = read_coordinates + Geocoder::Calculations.distance_between(mylat, mylon, lat, lon, :units => units) + end + + ## + # Get other geocoded objects within a given radius. + # + # <tt>:units</tt> :: <tt>:mi</tt> (default) or <tt>:km</tt> + # + def nearbys(radius = 20, units = :mi) + return [] unless geocoded? + options = {:exclude => self, :units => units} + self.class.near(read_coordinates, radius, options) + end + + ## + # Look up geographic data based on object attributes, + # and do something with it (requires a block). + # + def geocode(reverse = false, &block) + if reverse + lat_attr = self.class.geocoder_options[:latitude] + lon_attr = self.class.geocoder_options[:longitude] + unless lat_attr.is_a?(Symbol) and lon_attr.is_a?(Symbol) + raise Geocoder::ConfigurationError, + "You are attempting to fetch an address but have not specified " + + "attributes which provide coordinates for the object." + end + args = [send(lat_attr), send(lon_attr)] + else + address_method = self.class.geocoder_options[:user_address] + unless address_method.is_a? Symbol + raise Geocoder::ConfigurationError, + "You are attempting to geocode an object but have not specified " + + "a method which provides an address to search for." + end + args = [send(address_method)] + end + # passing a block to this method overrides the one given in the model + b = block_given?? block : self.class.geocoder_options[:block] + if result = Geocoder.search(*args).first + b.call(result) + end + end + end + end +end diff --git a/lib/geocoder/railtie.rb b/lib/geocoder/railtie.rb index 5c2296886186b4b17c5dc76583db31b2a90deeaa..0a15a0ffbf58fc8f79db33ceccdca832eb2650ee 100644 --- a/lib/geocoder/railtie.rb +++ b/lib/geocoder/railtie.rb @@ -1,4 +1,5 @@ require 'geocoder' +require 'geocoder/orms/active_record' module Geocoder if defined? Rails::Railtie @@ -55,12 +56,12 @@ module Geocoder end self.geocoder_options = options unless _geocoder_initialized? - include Geocoder::ActiveRecord + include Geocoder::Orm::ActiveRecord end end def self._geocoder_initialized? - included_modules.include? Geocoder::ActiveRecord + included_modules.include? Geocoder::Orm::ActiveRecord end end