rails-geocoder 0.9.2 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG.rdoc CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  Per-release changes to Geocoder.
4
4
 
5
+ == 0.9.3 (2010 Aug 2)
6
+
7
+ * Fix incompatibility with Rails 3 RC 1.
8
+ * Deprecate 'options' argument to 'nearbys' method.
9
+ * Allow inclusion of 'nearbys' in Arel method chains.
10
+
5
11
  == 0.9.2 (2010 Jun 3)
6
12
 
7
13
  * Fix LIMIT clause bug in PostgreSQL (reported by kenzie).
data/README.rdoc CHANGED
@@ -123,7 +123,7 @@ Please see the code for more methods and detailed information about arguments (e
123
123
 
124
124
  == SQLite
125
125
 
126
- SQLite's lack of trigonometric functions means Geocoder's default implementation of the +near+ method (scope) does not work. When using SQLite, Geocoder will automatically use a less accurate algorithm for finding objects near a given point. Results of this algorithm should not be trusted too much as it will return objects that are outside the given radius.
126
+ SQLite's lack of trigonometric functions requires an alternate implementation of the +near+ method (scope). When using SQLite, Geocoder will automatically use a less accurate algorithm for finding objects near a given point. Results of this algorithm should not be trusted too much as it will return objects that are outside the given radius.
127
127
 
128
128
 
129
129
  === Discussion
@@ -139,8 +139,21 @@ There are few options for finding objects near a given point in SQLite without i
139
139
  Because Geocoder needs to provide this functionality as a scope, we must go with option #1, but feel free to implement #2 or #3 if you need more accuracy.
140
140
 
141
141
 
142
+ == Known Issue
143
+
144
+ You cannot use the +near+ scope with another scope that provides an +includes+ option because the +SELECT+ clause generated by +near+ will overwrite it (or vice versa). Instead, try using +joins+ and pass a <tt>:select</tt> option to the +near+ scope to get the columns you want. For example, in Rails 2 syntax:
145
+
146
+ # instead of :includes => :venues:
147
+ City.near("Omaha, NE", 20, :select => "venues.*").all(:joins => :venues)
148
+
149
+ If anyone has a more elegant solution to this problem I am very interested in seeing it.
150
+
151
+
142
152
  == To-do List
143
153
 
154
+ * make 'near' scope work with 'select' options
155
+ * prepend table names to column names in SQL distance expression (required
156
+ to do joins on another geocoded model)
144
157
  * prevent NameError when GOOGLE_MAPS_API_KEY is missing: show nice msg
145
158
  * <tt>install.rb</tt> should do some setup when installed as a plugin
146
159
  * create initializer with GOOGLE_MAPS_API_KEY?
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.2
1
+ 0.9.3
data/lib/geocoder.rb CHANGED
@@ -52,6 +52,7 @@ module Geocoder
52
52
  # +order+ :: column(s) for ORDER BY SQL clause
53
53
  # +limit+ :: number of records to return (for LIMIT SQL clause)
54
54
  # +offset+ :: number of records to skip (for OFFSET SQL clause)
55
+ # +select+ :: string with the SELECT SQL fragment (e.g. “id, name”)
55
56
  #
56
57
  def near_scope_options(latitude, longitude, radius = 20, options = {})
57
58
  if ActiveRecord::Base.connection.adapter_name == "SQLite"
@@ -82,10 +83,7 @@ module Geocoder
82
83
  "POWER(SIN((#{longitude} - #{lon_attr}) * " +
83
84
  "PI() / 180 / 2), 2) ))"
84
85
  default_near_scope_options(latitude, longitude, radius, options).merge(
85
- :select => "*, #{distance} AS distance",
86
- :conditions => \
87
- ["#{lat_attr} BETWEEN ? AND ? AND #{lon_attr} BETWEEN ? AND ?"] +
88
- coordinate_bounds(latitude, longitude, radius),
86
+ :select => "#{options[:select] || '*'}, #{distance} AS distance",
89
87
  :having => "#{distance} <= #{radius}"
90
88
  )
91
89
  end
@@ -97,12 +95,8 @@ module Geocoder
97
95
  # objects outside the given radius).
98
96
  #
99
97
  def approx_near_scope_options(latitude, longitude, radius, options)
100
- lat_attr = geocoder_options[:latitude]
101
- lon_attr = geocoder_options[:longitude]
102
98
  default_near_scope_options(latitude, longitude, radius, options).merge(
103
- :conditions => \
104
- ["#{lat_attr} BETWEEN ? AND ? AND #{lon_attr} BETWEEN ? AND ?"] +
105
- coordinate_bounds(latitude, longitude, radius)
99
+ :select => options[:select] || nil
106
100
  )
107
101
  end
108
102
 
@@ -110,10 +104,29 @@ module Geocoder
110
104
  # Options used for any near-like scope.
111
105
  #
112
106
  def default_near_scope_options(latitude, longitude, radius, options)
107
+ lat_attr = geocoder_options[:latitude]
108
+ lon_attr = geocoder_options[:longitude]
109
+ conditions = \
110
+ ["#{lat_attr} BETWEEN ? AND ? AND #{lon_attr} BETWEEN ? AND ?"] +
111
+ coordinate_bounds(latitude, longitude, radius)
112
+
113
+ # Handle conditions. Passing of conditions by developers is deprecated
114
+ # but we will still need to handle conditions so, for example, we can
115
+ # exclude objects by ID from the nearbys method. This is incredibly
116
+ # ugly and doesn't work for a conditions hash: try using Arel?
117
+ if options[:conditions].is_a?(String)
118
+ options[:conditions] = [options[:conditions]]
119
+ end
120
+ if options[:conditions].is_a?(Array)
121
+ conditions[0] = "(#{conditions[0]}) AND #{options[:conditions][0]}"
122
+ conditions << options[:conditions][1]
123
+ end
124
+
113
125
  {
114
126
  :order => options[:order],
115
127
  :limit => options[:limit],
116
- :offset => options[:offset]
128
+ :offset => options[:offset],
129
+ :conditions => conditions
117
130
  }
118
131
  end
119
132
 
@@ -165,9 +178,17 @@ module Geocoder
165
178
  # (<tt>:order</tt>, <tt>:limit</tt>, and <tt>:offset</tt>).
166
179
  #
167
180
  def nearbys(radius = 20, options = {})
181
+ if options != {}
182
+ warn "DEPRECATION WARNING: The 'options' argument to the nearbys " +
183
+ "method is deprecated and will be removed from rails-geocoder in " +
184
+ "version 0.9.4. Nearbys now returns a scope so you should specify " +
185
+ "more scopes and/or conditions via chaining. For example: " +
186
+ "city.nearbys(20).order('name').limit(10). Support for Rails 2.x " +
187
+ "will be discontinued after rails-geocoder 0.9.3."
188
+ end
168
189
  return [] unless geocoded?
169
- options = {:conditions => ["id != ?", id]}.merge(options)
170
- self.class.near(read_coordinates, radius, options) - [self]
190
+ options.reverse_merge!(:conditions => ["id != ?", id])
191
+ self.class.near(read_coordinates, radius, options)
171
192
  end
172
193
 
173
194
  ##
@@ -175,14 +196,15 @@ module Geocoder
175
196
  # coordinates as an array: <tt>[lat, lon]</tt>.
176
197
  #
177
198
  def fetch_coordinates(save = false)
178
- location = send(self.class.geocoder_options[:method_name])
179
- returning Geocoder.fetch_coordinates(location) do |c|
180
- unless c.blank?
181
- method = (save ? "update" : "write") + "_attribute"
182
- send method, self.class.geocoder_options[:latitude], c[0]
183
- send method, self.class.geocoder_options[:longitude], c[1]
184
- end
199
+ coords = Geocoder.fetch_coordinates(
200
+ send(self.class.geocoder_options[:method_name])
201
+ )
202
+ unless coords.blank?
203
+ method = (save ? "update" : "write") + "_attribute"
204
+ send method, self.class.geocoder_options[:latitude], coords[0]
205
+ send method, self.class.geocoder_options[:longitude], coords[1]
185
206
  end
207
+ coords
186
208
  end
187
209
 
188
210
  ##
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rails-geocoder}
8
- s.version = "0.9.2"
8
+ s.version = "0.9.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Alex Reisner"]
12
- s.date = %q{2010-06-03}
12
+ s.date = %q{2010-08-02}
13
13
  s.description = %q{Geocoder adds object geocoding and database-agnostic distance calculations to Ruby on Rails. It does not rely on proprietary database functions so finding geocoded objects in a given area is easily done using out-of-the-box MySQL or even SQLite.}
14
14
  s.email = %q{alex@alexreisner.com}
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 9
8
- - 2
9
- version: 0.9.2
8
+ - 3
9
+ version: 0.9.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - Alex Reisner
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-03 00:00:00 -04:00
17
+ date: 2010-08-02 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies: []
20
20