Skip to content
Snippets Groups Projects
Commit 2b69ba59 authored by Alex Reisner's avatar Alex Reisner
Browse files

Remove Rails 2-specific code.

Stop allowing full :conditions option to near_scope_options (was
deprecated, now it's gone). Update installation documentation.
parent 3b53f0ee
Branches
Tags
No related merge requests found
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
Per-release changes to Geocoder. Per-release changes to Geocoder.
== 0.9.5 (TBA)
* Don't allow :conditions hash in 'options' argument to 'nearbys' method (was deprecated in 0.9.3).
* Separate Rails 2 and Rails 3-compatible branches.
* Switch from Google's XML to JSON geocoding API.
== 0.9.4 (2010 Aug 2) == 0.9.4 (2010 Aug 2)
* Google Maps API key no longer required (uses geocoder v3). * Google Maps API key no longer required (uses geocoder v3).
......
...@@ -2,27 +2,12 @@ ...@@ -2,27 +2,12 @@
Geocoder adds object geocoding and database-agnostic distance calculations to Ruby on Rails. It's as simple as calling <tt>fetch_coordinates!</tt> on your objects, and then using a scope like <tt>Venue.near("Billings, MT")</tt>. Since it does not rely on proprietary database functions finding geocoded objects in a given area works with out-of-the-box MySQL or even SQLite. Geocoder adds object geocoding and database-agnostic distance calculations to Ruby on Rails. It's as simple as calling <tt>fetch_coordinates!</tt> on your objects, and then using a scope like <tt>Venue.near("Billings, MT")</tt>. Since it does not rely on proprietary database functions finding geocoded objects in a given area works with out-of-the-box MySQL or even SQLite.
<b>Geocoder is currently compatible with Rails 2.x and Rails 3.</b> Also, a Google Maps API key is no longer necessary. <b>Geocoder is compatible with Rails 2 (see the rails2 branch) and Rails 3.</b>
== 1. Install == 1. Install
=== a. Rails 2 === a. Rails 3
Install either as a plugin:
script/plugin install git://github.com/alexreisner/geocoder.git
or as a gem:
# add to config/environment.rb:
config.gem "rails-geocoder", :lib => "geocoder", :source => "http://gemcutter.org/"
# at command prompt:
sudo rake gems:install
=== b. Rails 3
Install either as a plugin: Install either as a plugin:
...@@ -37,6 +22,13 @@ or as a gem: ...@@ -37,6 +22,13 @@ or as a gem:
bundle install bundle install
=== b. Rails 2
Install as a plugin from the rails2 branch:
script/plugin install git://github.com/alexreisner/geocoder.git -r rails2
== 2. Configure == 2. Configure
A) Add +latitude+ and +longitude+ columns to your model: A) Add +latitude+ and +longitude+ columns to your model:
...@@ -144,12 +136,20 @@ If anyone has a more elegant solution to this problem I am very interested in se ...@@ -144,12 +136,20 @@ If anyone has a more elegant solution to this problem I am very interested in se
== To-do List == To-do List
* fix Postgres problem (http://github.com/alexreisner/geocoder/issues#issue/5)
* use completely separate "drivers" for different AR adapters?
* seems reasonable since we're using very DB-specific features
* also need to make sure 'mysql2' is supported
* add reverse geocoding * add reverse geocoding
* restructure as Railtie * restructure as Railtie
* http://www.igvita.com/2010/08/04/rails-3-internals-railtie-creating-plugins/ * http://www.igvita.com/2010/08/04/rails-3-internals-railtie-creating-plugins/
* make 'near' scope work with 'select' options * make 'near' scope work with 'select' options
* make 'near' scope work with AR associations
* http://stackoverflow.com/questions/3266358/geocoder-rails-plugin-near-search-problem-with-activerecord
* prepend table names to column names in SQL distance expression (required * prepend table names to column names in SQL distance expression (required
to do joins on another geocoded model) to do joins on another geocoded model)
* unobtrusively add ability to get a result with more data (Geocoder object?)
* the default usage should remain dead simple
Copyright (c) 2009-10 Alex Reisner, released under the MIT license Copyright (c) 2009-10 Alex Reisner, released under the MIT license
...@@ -11,21 +11,21 @@ module Geocoder ...@@ -11,21 +11,21 @@ module Geocoder
base.class_eval do base.class_eval do
# scope: geocoded objects # scope: geocoded objects
send(Geocoder.scope_method_name, :geocoded, scope :geocoded,
:conditions => "#{geocoder_options[:latitude]} IS NOT NULL " + :conditions => "#{geocoder_options[:latitude]} IS NOT NULL " +
"AND #{geocoder_options[:longitude]} IS NOT NULL") "AND #{geocoder_options[:longitude]} IS NOT NULL"
# scope: not-geocoded objects # scope: not-geocoded objects
send(Geocoder.scope_method_name, :not_geocoded, scope :not_geocoded,
:conditions => "#{geocoder_options[:latitude]} IS NULL " + :conditions => "#{geocoder_options[:latitude]} IS NULL " +
"OR #{geocoder_options[:longitude]} IS NULL") "OR #{geocoder_options[:longitude]} IS NULL"
## ##
# Find all objects within a radius (in miles) of the given location # Find all objects within a radius (in miles) of the given location
# (address string). Location (the first argument) may be either a string # (address string). Location (the first argument) may be either a string
# to geocode or an array of coordinates (<tt>[lat,long]</tt>). # to geocode or an array of coordinates (<tt>[lat,long]</tt>).
# #
send(Geocoder.scope_method_name, :near, lambda{ |location, *args| scope :near, lambda{ |location, *args|
latitude, longitude = location.is_a?(Array) ? latitude, longitude = location.is_a?(Array) ?
location : Geocoder.fetch_coordinates(location) location : Geocoder.fetch_coordinates(location)
if latitude and longitude if latitude and longitude
...@@ -33,7 +33,7 @@ module Geocoder ...@@ -33,7 +33,7 @@ module Geocoder
else else
{} {}
end end
}) }
end end
end end
...@@ -48,6 +48,7 @@ module Geocoder ...@@ -48,6 +48,7 @@ module Geocoder
# Options hash may include: # Options hash may include:
# #
# +units+ :: <tt>:mi</tt> (default) or <tt>:km</tt> # +units+ :: <tt>:mi</tt> (default) or <tt>:km</tt>
# +exclude+ :: exclude the given object (used by the #nearbys method)
# +order+ :: column(s) for ORDER BY SQL clause # +order+ :: column(s) for ORDER BY SQL clause
# +limit+ :: number of records to return (for LIMIT SQL clause) # +limit+ :: number of records to return (for LIMIT SQL clause)
# +offset+ :: number of records to skip (for OFFSET SQL clause) # +offset+ :: number of records to skip (for OFFSET SQL clause)
...@@ -109,24 +110,11 @@ module Geocoder ...@@ -109,24 +110,11 @@ module Geocoder
conditions = \ conditions = \
["#{lat_attr} BETWEEN ? AND ? AND #{lon_attr} BETWEEN ? AND ?"] + ["#{lat_attr} BETWEEN ? AND ? AND #{lon_attr} BETWEEN ? AND ?"] +
coordinate_bounds(latitude, longitude, radius) coordinate_bounds(latitude, longitude, radius)
# Handle conditions. Passing of conditions by developers is deprecated
# but we will still need to handle conditions so, for example, we can
# exclude objects by ID from the nearbys method. This is incredibly
# ugly and doesn't work for a conditions hash: try using Arel?
if options[:conditions].is_a?(String)
options[:conditions] = [options[:conditions]]
end
if options[:conditions].is_a?(Array)
conditions[0] = "(#{conditions[0]}) AND #{options[:conditions][0]}"
conditions << options[:conditions][1]
end
{ {
:order => options[:order], :order => options[:order],
:limit => options[:limit], :limit => options[:limit],
:offset => options[:offset], :offset => options[:offset],
:conditions => conditions :conditions => (obj = options[:exclude]) ? ["id != ?", obj.id] : nil
} }
end end
...@@ -184,21 +172,8 @@ module Geocoder ...@@ -184,21 +172,8 @@ module Geocoder
# Valid units are defined in <tt>distance_between</tt> class method. # Valid units are defined in <tt>distance_between</tt> class method.
# #
def nearbys(radius = 20, units = :mi) def nearbys(radius = 20, units = :mi)
options = {:conditions => ["id != ?", id]}
if units.is_a? Hash
warn "DEPRECATION WARNING: The 'options' argument to the nearbys " +
"method is deprecated and will be removed from rails-geocoder in " +
"a future version. The second argument is now called 'units' and " +
"should be a symbol (:mi or :km, :mi is the default). The 'nearbys' " +
"method now returns a Rails 3 scope so you should specify more " +
"scopes and/or conditions via chaining. For example: " +
"city.nearbys(20).order('name').limit(10). Support for Rails 2.x " +
"will eventually be discontinued."
options.reverse_merge!(units)
else
options.reverse_merge!(:units => units)
end
return [] unless geocoded? return [] unless geocoded?
options = {:exclude => self, :units => units}
self.class.near(read_coordinates, radius, options) self.class.near(read_coordinates, radius, options)
end end
...@@ -314,7 +289,7 @@ module Geocoder ...@@ -314,7 +289,7 @@ module Geocoder
# #
def self.search(query) def self.search(query)
doc = _fetch_parsed_response(query) doc = _fetch_parsed_response(query)
doc['status'] == "OK" ? doc : nil doc && doc['status'] == "OK" ? doc : nil
end end
## ##
...@@ -359,17 +334,6 @@ module Geocoder ...@@ -359,17 +334,6 @@ module Geocoder
return nil return nil
end end
end end
##
# Name of the ActiveRecord scope method.
#
def self.scope_method_name
begin
Rails.version.starts_with?("3") ? :scope : :named_scope
rescue NameError
:named_scope
end
end
end end
## ##
......
...@@ -27,7 +27,7 @@ module ActiveRecord ...@@ -27,7 +27,7 @@ module ActiveRecord
write_attribute(attr_name.to_sym, value) write_attribute(attr_name.to_sym, value)
end end
def self.named_scope(*args); end def self.scope(*args); end
end end
end end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment