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

Make fetch_coordinates assign coordinates; fetch_coordinates! also saves attributes.

parent 6b7114ce
No related branches found
No related tags found
No related merge requests found
......@@ -35,8 +35,8 @@ Add +latitude+ and +longitude+ columns to your model:
Then tell your model about it:
geocoded_by :address # attribute/method to use for geocoding
after_validation :fetch_coordinates! # fetch and assign coordinates before saving
geocoded_by :address # attribute/method to use for geocoding
after_validation :fetch_coordinates # fetch and assign coordinates before saving
You are not stuck with the +latitude+ and +longitude+ column names, or the +address+ method. See "More On Configuration" below for details.
......@@ -52,8 +52,8 @@ Assuming +Venue+ is a geocoded model, it has the following named scopes:
Assuming +obj+ has a valid string for its +location+:
obj.fetch_coordinates # returns coordinates [lat, lon]
obj.fetch_coordinates! # also writes coordinates to object
obj.fetch_coordinates # fetches and assigns coordinates
obj.fetch_coordinates! # also saves lat, lon attributes
Assuming +obj+ is geocoded (has latitude and longitude):
......@@ -97,7 +97,6 @@ Please see the code for more methods and detailed information about arguments (e
* rake task for geocoding all non-geocoded objects
* <tt>install.rb</tt> should do some setup when installed as a plugin
* make <tt>fetch_coordinates</tt> assign coordinates; <tt>fetch_coordinates!</tt> should also save object
Copyright (c) 2009 Alex Reisner, released under the MIT license
......@@ -121,8 +121,8 @@ module Geocoder
end
##
# Calculate the distance from the object to a point (lat,lon). Valid units
# are defined in <tt>distance_between</tt> class method.
# Calculate the distance from the object to a point (lat,lon).
# Valid units are defined in <tt>distance_between</tt> class method.
#
def distance_to(lat, lon, units = :mi)
return nil unless geocoded?
......@@ -131,44 +131,37 @@ module Geocoder
end
##
# Get other geocoded objects within a given radius (in miles). This method
# calls the +near+ named scope with the object's coordinates as the first
# argument (the object must be geocoded before this method is called).
#
# You may pass the radius and options arguments as well, but if you
# specify <tt>:conditions</tt> in the options hash you must manually
# omit +self+ from the list of results. You should try to avoid this
# anyway, and use other named scopes to apply further conditions, eg:
#
# venue.nearbys(10).open_on_mondays
# venue.nearbys.with_capacity(2000)
# Get other geocoded objects within a given radius (in miles). Takes a
# radius (in miles) and options for passing to the +near+ named scope
# (<tt>:order</tt>, <tt>:limit</tt>, and <tt>:offset</tt>).
#
def nearbys(radius = 20, options = {})
return [] unless geocoded?
coords = self.class._get_coordinates(self)
options = {:conditions => ["id != ?", id]}.merge(options)
self.class.near(coords, radius, options)
self.class.near(coords, radius, options) - [self]
end
##
# Fetch coordinates based on the object's location.
# Returns an array <tt>[lat, lon]</tt>.
# Fetch coordinates and assign +latitude+ and +longitude+. Also returns
# coordinates as an array: <tt>[lat, lon]</tt>.
#
def fetch_coordinates
def fetch_coordinates(save = false)
location = send(self.class.geocoder_options[:method_name])
Geocoder.fetch_coordinates(location)
returning Geocoder.fetch_coordinates(location) do |c|
unless c.blank?
method = (save ? "update" : "write") + "_attribute"
send method, self.class.geocoder_options[:latitude], c[0]
send method, self.class.geocoder_options[:longitude], c[1]
end
end
end
##
# Fetch coordinates and assign +latitude+ and +longitude+.
# Fetch coordinates and update (save) +latitude+ and +longitude+ data.
#
def fetch_coordinates!
returning fetch_coordinates do |c|
unless c.blank?
write_attribute(self.class.geocoder_options[:latitude], c[0])
write_attribute(self.class.geocoder_options[:longitude], c[1])
end
end
fetch_coordinates(true)
end
##
......@@ -194,7 +187,7 @@ module Geocoder
# Calculate the distance between two points on Earth (Haversine formula).
# Takes two sets of coordinates and an options hash:
#
# +units+ :: <tt>:mi</tt> for miles (default), <tt>:km</tt> for kilometers
# <tt>:units</tt> :: <tt>:mi</tt> (default) or <tt>:km</tt>
#
def self.distance_between(lat1, lon1, lat2, lon2, options = {})
......
......@@ -5,11 +5,6 @@ class GeocoderTest < Test::Unit::TestCase
def test_fetch_coordinates
v = Venue.new(*venue_params(:msg))
assert_equal [40.7495760, -73.9916733], v.fetch_coordinates
end
def test_fetch_coordinates!
v = Venue.new(*venue_params(:msg))
v.fetch_coordinates!
assert_equal [40.7495760, -73.9916733], [v.latitude, v.longitude]
end
end
......@@ -24,6 +24,10 @@ module ActiveRecord
@attributes[attr_name] = value
end
def update_attribute(attr_name, value)
write_attribute(attr_name, value)
end
def self.named_scope(*args); end
end
end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment