Permalink
Browse files

Added ability for finders to accept :units and :formula as options to…

… override defaults set by acts_as_mappable.

git-svn-id: http://geokit.rubyforge.org/svn/trunk@13 9265c765-0211-4c68-b2df-6d1bd6e20c4d
  • Loading branch information...
1 parent 9c0303d commit b7115607a9c7037b662c5e6350f0b5f852468ec1 bill_eisenhauer committed Feb 12, 2007
Showing with 36 additions and 6 deletions.
  1. +26 −6 lib/geo_kit/acts_as_mappable.rb
  2. +10 −0 test/acts_as_mappable_test.rb
@@ -62,8 +62,10 @@ module SingletonMethods # :nodoc:
def find(*args)
options = extract_options_from_args!(args)
origin = extract_origin_from_options(options)
- add_distance_to_select(options, origin) if origin
- substitute_distance_in_conditions(options, origin) if origin && options.has_key?(:conditions)
+ units = extract_units_from_options(options)
+ formula = extract_formula_from_options(options)
+ add_distance_to_select(options, origin, units, formula) if origin
+ substitute_distance_in_conditions(options, origin, units, formula) if origin && options.has_key?(:conditions)
args.push(options)
super(*args)
end
@@ -123,6 +125,24 @@ def extract_origin_from_options(options)
origin
end
+ # Extract the units out of the options if it exists and returns it. If
+ # there is no :units key, it uses the default. The side effect of the
+ # method is to remove the :units key from the options hash.
+ def extract_units_from_options(options)
+ units = options[:units] || default_units
+ options.delete(:units)
+ units
+ end
+
+ # Extract the formula out of the options if it exists and returns it. If
+ # there is no :formula key, it uses the default. The side effect of the
+ # method is to remove the :formula key from the options hash.
+ def extract_formula_from_options(options)
+ formula = options[:formula] || default_formula
+ options.delete(:formula)
+ formula
+ end
+
# Geocodes the origin which was passed in String form. The string needs
# to be classified so that the appropriate geocoding technique can be
# used. Strings can be either IP addresses or physical addresses. The
@@ -148,9 +168,9 @@ def geocode_physical_address(origin)
end
# Augments the select with the distance SQL.
- def add_distance_to_select(options, origin)
+ def add_distance_to_select(options, origin, units=default_units, formula=default_formula)
if origin
- distance_selector = distance_sql(origin, default_units, default_formula) + " AS #{distance_column_name}"
+ distance_selector = distance_sql(origin, units, formula) + " AS #{distance_column_name}"
selector = options.has_key?(:select) && options[:select] ? options[:select] : "*"
options[:select] = "#{selector}, #{distance_selector}"
end
@@ -160,11 +180,11 @@ def add_distance_to_select(options, origin)
# passed in and the distance column exists, we leave it to be flagged as bad SQL by the database.
# Conditions are either a string or an array. In the case of an array, the first entry contains
# the condition.
- def substitute_distance_in_conditions(options, origin)
+ def substitute_distance_in_conditions(options, origin, units=default_units, formula=default_formula)
original_conditions = options[:conditions]
condition = original_conditions.is_a?(String) ? original_conditions : original_conditions.first
pattern = Regexp.new("\s*#{distance_column_name}(\s<>=)*")
- condition = condition.gsub(pattern, distance_sql(origin, default_units, default_formula))
+ condition = condition.gsub(pattern, distance_sql(origin, units, formula))
original_conditions = condition if original_conditions.is_a?(String)
original_conditions[0] = condition if original_conditions.is_a?(Array)
options[:conditions] = original_conditions
@@ -76,6 +76,16 @@ def test_find_with_distance_condition
assert_equal 5, locations.size
end
+ def test_find_with_distance_condition_with_units_override
+ locations = Location.find(:all, :origin => @loc_a, :units => :kms, :conditions => "distance < 6.387")
+ assert_equal 5, locations.size
+ end
+
+ def test_find_with_distance_condition_with_formula_override
+ locations = Location.find(:all, :origin => @loc_a, :formula => :flat, :conditions => "distance < 6.387")
+ assert_equal 6, locations.size
+ end
+
def test_find_within
locations = Location.find_within(3.97, :origin => @loc_a)
assert_equal 5, locations.size

0 comments on commit b711560

Please sign in to comment.