rails-geocoder 0.9.4 → 0.9.5

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,13 @@
2
2
 
3
3
  Per-release changes to Geocoder.
4
4
 
5
+ == 0.9.5 (2010 Oct 15)
6
+
7
+ * Fix broken PostgreSQL compatibility (now 100% compatible).
8
+ * Switch from Google's XML to JSON geocoding API.
9
+ * Separate Rails 2 and Rails 3-compatible branches.
10
+ * Don't allow :conditions hash in 'options' argument to 'nearbys' method (was deprecated in 0.9.3).
11
+
5
12
  == 0.9.4 (2010 Aug 2)
6
13
 
7
14
  * Google Maps API key no longer required (uses geocoder v3).
data/README.rdoc CHANGED
@@ -2,46 +2,33 @@
2
2
 
3
3
  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.
4
4
 
5
- <b>Geocoder is currently compatible with Rails 2.x and Rails 3.</b> Also, a Google Maps API key is no longer necessary.
5
+ Geocoder is compatible with Rails 2.x and 3.x. <b>This is the README for the 3.x branch.</b> Please see the 2.x branch for installation instructions, documentation, and issues.
6
6
 
7
7
 
8
8
  == 1. Install
9
9
 
10
- === a. Rails 2
10
+ === As a Gem
11
11
 
12
- Install either as a plugin:
12
+ Add this to your Gemfile:
13
13
 
14
- script/plugin install git://github.com/alexreisner/geocoder.git
15
-
16
- or as a gem:
14
+ gem "rails-geocoder", :require => "geocoder"
17
15
 
18
- # add to config/environment.rb:
19
- config.gem "rails-geocoder", :lib => "geocoder", :source => "http://gemcutter.org/"
20
-
21
- # at command prompt:
22
- sudo rake gems:install
16
+ and run this at the command prompt:
23
17
 
18
+ bundle install
24
19
 
25
- === b. Rails 3
20
+ === Or As a Plugin
26
21
 
27
- Install either as a plugin:
22
+ At the command prompt:
28
23
 
29
24
  rails plugin install git://github.com/alexreisner/geocoder.git
30
25
 
31
- or as a gem:
32
-
33
- # add to Gemfile:
34
- gem "rails-geocoder", :require => "geocoder"
35
-
36
- # at command prompt:
37
- bundle install
38
-
39
26
 
40
27
  == 2. Configure
41
28
 
42
29
  A) Add +latitude+ and +longitude+ columns to your model:
43
30
 
44
- script/generate migration AddLatitudeAndLongitudeToYourModel latitude:float longitude:float
31
+ rails generate migration AddLatitudeAndLongitudeToYourModel latitude:float longitude:float
45
32
  rake db:migrate
46
33
 
47
34
  B) Tell geocoder where your model stores its address:
@@ -82,10 +69,10 @@ Some utility methods are also available:
82
69
 
83
70
  # distance (in miles) between Eiffel Tower and Empire State Building
84
71
  Geocoder.distance_between( 48.858205,2.294359, 40.748433,-73.985655 )
85
-
72
+
86
73
  # look up coordinates of some location (like searching Google Maps)
87
74
  Geocoder.fetch_coordinates("25 Main St, Cooperstown, NY")
88
-
75
+
89
76
  # find the geographic center (aka center of gravity) of objects or points
90
77
  Geocoder.geographic_center([ city1, city2, city3, [40.22,-73.99], city4 ])
91
78
 
@@ -144,9 +131,16 @@ If anyone has a more elegant solution to this problem I am very interested in se
144
131
 
145
132
  == To-do List
146
133
 
147
- * make 'near' scope work with 'select' options
134
+ * use completely separate "drivers" for different AR adapters?
135
+ * seems reasonable since we're using very DB-specific features
136
+ * also need to make sure 'mysql2' is supported
137
+ * add reverse geocoding
138
+ * make 'near' scope work with AR associations
139
+ * http://stackoverflow.com/questions/3266358/geocoder-rails-plugin-near-search-problem-with-activerecord
148
140
  * prepend table names to column names in SQL distance expression (required
149
141
  to do joins on another geocoded model)
142
+ * unobtrusively add ability to get a result with more data (Geocoder object?)
143
+ * the default usage should remain dead simple
150
144
 
151
145
 
152
146
  Copyright (c) 2009-10 Alex Reisner, released under the MIT license
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.4
1
+ 0.9.5
data/lib/geocoder.rb CHANGED
@@ -1,10 +1,8 @@
1
- require 'rexml/document'
2
-
3
1
  ##
4
2
  # Add geocoding functionality (via Google) to any object.
5
3
  #
6
4
  module Geocoder
7
-
5
+
8
6
  ##
9
7
  # Implementation of 'included' hook method.
10
8
  #
@@ -13,21 +11,21 @@ module Geocoder
13
11
  base.class_eval do
14
12
 
15
13
  # scope: geocoded objects
16
- send(Geocoder.scope_method_name, :geocoded,
14
+ scope :geocoded,
17
15
  :conditions => "#{geocoder_options[:latitude]} IS NOT NULL " +
18
- "AND #{geocoder_options[:longitude]} IS NOT NULL")
16
+ "AND #{geocoder_options[:longitude]} IS NOT NULL"
19
17
 
20
18
  # scope: not-geocoded objects
21
- send(Geocoder.scope_method_name, :not_geocoded,
19
+ scope :not_geocoded,
22
20
  :conditions => "#{geocoder_options[:latitude]} IS NULL " +
23
- "OR #{geocoder_options[:longitude]} IS NULL")
24
-
21
+ "OR #{geocoder_options[:longitude]} IS NULL"
22
+
25
23
  ##
26
24
  # Find all objects within a radius (in miles) of the given location
27
25
  # (address string). Location (the first argument) may be either a string
28
26
  # to geocode or an array of coordinates (<tt>[lat,long]</tt>).
29
27
  #
30
- send(Geocoder.scope_method_name, :near, lambda{ |location, *args|
28
+ scope :near, lambda{ |location, *args|
31
29
  latitude, longitude = location.is_a?(Array) ?
32
30
  location : Geocoder.fetch_coordinates(location)
33
31
  if latitude and longitude
@@ -35,10 +33,10 @@ module Geocoder
35
33
  else
36
34
  {}
37
35
  end
38
- })
36
+ }
39
37
  end
40
38
  end
41
-
39
+
42
40
  ##
43
41
  # Methods which will be class methods of the including class.
44
42
  #
@@ -48,13 +46,16 @@ module Geocoder
48
46
  # Get options hash suitable for passing to ActiveRecord.find to get
49
47
  # records within a radius (in miles) of the given point.
50
48
  # Options hash may include:
51
- #
52
- # +order+ :: column(s) for ORDER BY SQL clause
53
- # +limit+ :: number of records to return (for LIMIT SQL clause)
54
- # +offset+ :: number of records to skip (for OFFSET SQL clause)
55
- # +select+ :: string with the SELECT SQL fragment (e.g. “id, name”)
49
+ #
50
+ # +units+ :: <tt>:mi</tt> (default) or <tt>:km</tt>
51
+ # +exclude+ :: an object to exclude (used by the #nearbys method)
52
+ # +order+ :: column(s) for ORDER BY SQL clause
53
+ # +limit+ :: number of records to return (for LIMIT SQL clause)
54
+ # +offset+ :: number of records to skip (for OFFSET SQL clause)
55
+ # +select+ :: string with the SELECT SQL fragment (e.g. “id, name”)
56
56
  #
57
57
  def near_scope_options(latitude, longitude, radius = 20, options = {})
58
+ radius *= km_in_mi if options[:units] == :km
58
59
  if ActiveRecord::Base.connection.adapter_name == "SQLite"
59
60
  approx_near_scope_options(latitude, longitude, radius, options)
60
61
  else
@@ -68,7 +69,7 @@ module Geocoder
68
69
  ##
69
70
  # Scope options hash for use with a database that supports POWER(),
70
71
  # SQRT(), PI(), and trigonometric functions (SIN(), COS(), and ASIN()).
71
- #
72
+ #
72
73
  # Taken from the excellent tutorial at:
73
74
  # http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL
74
75
  #
@@ -99,7 +100,7 @@ module Geocoder
99
100
  :select => options[:select] || nil
100
101
  )
101
102
  end
102
-
103
+
103
104
  ##
104
105
  # Options used for any near-like scope.
105
106
  #
@@ -109,27 +110,19 @@ module Geocoder
109
110
  conditions = \
110
111
  ["#{lat_attr} BETWEEN ? AND ? AND #{lon_attr} BETWEEN ? AND ?"] +
111
112
  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]
113
+ if obj = options[:exclude]
114
+ conditions[0] << " AND id != ?"
115
+ conditions << obj.id
123
116
  end
124
-
125
117
  {
118
+ :group => columns.map{ |c| c.name}.join(','),
126
119
  :order => options[:order],
127
120
  :limit => options[:limit],
128
121
  :offset => options[:offset],
129
122
  :conditions => conditions
130
123
  }
131
124
  end
132
-
125
+
133
126
  ##
134
127
  # Get the rough high/low lat/long bounds for a geographic point and
135
128
  # radius. Returns an array: <tt>[lat_lo, lat_hi, lon_lo, lon_hi]</tt>.
@@ -145,6 +138,13 @@ module Geocoder
145
138
  longitude + (radius / factor)
146
139
  ]
147
140
  end
141
+
142
+ ##
143
+ # Conversion factor: km to mi.
144
+ #
145
+ def km_in_mi
146
+ 0.621371192
147
+ end
148
148
  end
149
149
 
150
150
  ##
@@ -161,7 +161,7 @@ module Geocoder
161
161
  def geocoded?
162
162
  read_coordinates.compact.size > 0
163
163
  end
164
-
164
+
165
165
  ##
166
166
  # Calculate the distance from the object to a point (lat,lon).
167
167
  # Valid units are defined in <tt>distance_between</tt> class method.
@@ -171,26 +171,17 @@ module Geocoder
171
171
  mylat,mylon = read_coordinates
172
172
  Geocoder.distance_between(mylat, mylon, lat, lon, :units => units)
173
173
  end
174
-
174
+
175
175
  ##
176
- # Get other geocoded objects within a given radius (in miles). Takes a
177
- # radius (in miles) and options for passing to the +near+ scope
178
- # (<tt>:order</tt>, <tt>:limit</tt>, and <tt>:offset</tt>).
176
+ # Get other geocoded objects within a given radius.
177
+ # Valid units are defined in <tt>distance_between</tt> class method.
179
178
  #
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
- "a future version. Nearbys now returns a scope so you should " +
185
- "specify 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 soon."
188
- end
179
+ def nearbys(radius = 20, units = :mi)
189
180
  return [] unless geocoded?
190
- options.reverse_merge!(:conditions => ["id != ?", id])
181
+ options = {:exclude => self, :units => units}
191
182
  self.class.near(read_coordinates, radius, options)
192
183
  end
193
-
184
+
194
185
  ##
195
186
  # Fetch coordinates and assign +latitude+ and +longitude+. Also returns
196
187
  # coordinates as an array: <tt>[lat, lon]</tt>.
@@ -214,55 +205,36 @@ module Geocoder
214
205
  fetch_coordinates(true)
215
206
  end
216
207
 
217
- ##
218
- # Query Google for the coordinates of the given phrase.
219
- # Returns array [lat,lon] if found, nil if not found or if network error.
220
- #
221
- def self.fetch_coordinates(query)
222
- return nil if query.blank?
223
- return nil unless doc = self.search(query)
224
-
225
- # make sure search found a result
226
- e = doc.elements['GeocodeResponse/status']
227
- return nil unless (e and e.text == "OK")
228
-
229
- # isolate the relevant part of the result
230
- place = doc.elements['GeocodeResponse/result/geometry/location']
231
-
232
- # blindly use the first results (assume they are most accurate)
233
- ['lat', 'lng'].map{ |i| place.elements[i].text.to_f }
234
- end
235
-
236
208
  ##
237
209
  # Calculate the distance between two points on Earth (Haversine formula).
238
210
  # Takes two sets of coordinates and an options hash:
239
- #
211
+ #
240
212
  # <tt>:units</tt> :: <tt>:mi</tt> (default) or <tt>:km</tt>
241
213
  #
242
214
  def self.distance_between(lat1, lon1, lat2, lon2, options = {})
243
-
215
+
244
216
  # set default options
245
217
  options[:units] ||= :mi
246
-
218
+
247
219
  # define conversion factors
248
- units = { :mi => 3956, :km => 6371 }
249
-
220
+ conversions = { :mi => 3956, :km => 6371 }
221
+
250
222
  # convert degrees to radians
251
223
  lat1 = to_radians(lat1)
252
224
  lon1 = to_radians(lon1)
253
225
  lat2 = to_radians(lat2)
254
226
  lon2 = to_radians(lon2)
255
-
227
+
256
228
  # compute distances
257
229
  dlat = (lat1 - lat2).abs
258
230
  dlon = (lon1 - lon2).abs
259
-
231
+
260
232
  a = (Math.sin(dlat / 2))**2 + Math.cos(lat1) *
261
- (Math.sin(dlon / 2))**2 * Math.cos(lat2)
262
- c = 2 * Math.atan2( Math.sqrt(a), Math.sqrt(1-a))
263
- c * units[options[:units]]
233
+ (Math.sin(dlon / 2))**2 * Math.cos(lat2)
234
+ c = 2 * Math.atan2( Math.sqrt(a), Math.sqrt(1-a))
235
+ c * conversions[options[:units]]
264
236
  end
265
-
237
+
266
238
  ##
267
239
  # Compute the geographic center (aka geographic midpoint, center of
268
240
  # gravity) for an array of geocoded objects and/or [lat,lon] arrays
@@ -270,15 +242,15 @@ module Geocoder
270
242
  # the procedure documented at http://www.geomidpoint.com/calculation.html.
271
243
  #
272
244
  def self.geographic_center(points)
273
-
245
+
274
246
  # convert objects to [lat,lon] arrays and remove nils
275
247
  points = points.map{ |p|
276
248
  p.is_a?(Array) ? p : (p.geocoded?? p.read_coordinates : nil)
277
249
  }.compact
278
-
250
+
279
251
  # convert degrees to radians
280
252
  points.map!{ |p| [to_radians(p[0]), to_radians(p[1])] }
281
-
253
+
282
254
  # convert to Cartesian coordinates
283
255
  x = []; y = []; z = []
284
256
  points.each do |p|
@@ -291,12 +263,12 @@ module Geocoder
291
263
  xa, ya, za = [x,y,z].map do |c|
292
264
  c.inject(0){ |tot,i| tot += i } / c.size.to_f
293
265
  end
294
-
266
+
295
267
  # convert back to latitude/longitude
296
268
  lon = Math.atan2(ya, xa)
297
269
  hyp = Math.sqrt(xa**2 + ya**2)
298
270
  lat = Math.atan2(za, hyp)
299
-
271
+
300
272
  # return answer in degrees
301
273
  [to_degrees(lat), to_degrees(lon)]
302
274
  end
@@ -307,35 +279,57 @@ module Geocoder
307
279
  def self.to_radians(degrees)
308
280
  degrees * (Math::PI / 180)
309
281
  end
310
-
282
+
311
283
  ##
312
284
  # Convert radians to degrees.
313
285
  #
314
286
  def self.to_degrees(radians)
315
287
  (radians * 180.0) / Math::PI
316
288
  end
317
-
289
+
318
290
  ##
319
291
  # Query Google for geographic information about the given phrase.
292
+ # Returns a hash representing a valid geocoder response.
293
+ # Returns nil if non-200 HTTP response, timeout, or other error.
320
294
  #
321
295
  def self.search(query)
322
- if doc = _fetch_xml(query)
323
- REXML::Document.new(doc)
296
+ doc = _fetch_parsed_response(query)
297
+ doc && doc['status'] == "OK" ? doc : nil
298
+ end
299
+
300
+ ##
301
+ # Query Google for the coordinates of the given phrase.
302
+ # Returns array [lat,lon] if found, nil if not found or if network error.
303
+ #
304
+ def self.fetch_coordinates(query)
305
+ return nil unless doc = self.search(query)
306
+ # blindly use the first results (assume they are most accurate)
307
+ place = doc['results'].first['geometry']['location']
308
+ ['lat', 'lng'].map{ |i| place[i] }
309
+ end
310
+
311
+ ##
312
+ # Returns a parsed Google geocoder search result (hash).
313
+ # This method is not intended for general use (prefer Geocoder.search).
314
+ #
315
+ def self._fetch_parsed_response(query)
316
+ if doc = _fetch_raw_response(query)
317
+ ActiveSupport::JSON.decode(doc)
324
318
  end
325
319
  end
326
-
320
+
327
321
  ##
328
- # Request an XML geo search result from Google.
322
+ # Returns a raw Google geocoder search result (JSON).
329
323
  # This method is not intended for general use (prefer Geocoder.search).
330
324
  #
331
- def self._fetch_xml(query)
332
- params = {
333
- :address => query,
334
- :sensor => "false"
335
- }
336
- url = "http://maps.google.com/maps/api/geocode/xml?" + params.to_query
337
-
338
- # Query geocoder and make sure it responds quickly.
325
+ def self._fetch_raw_response(query)
326
+ return nil if query.blank?
327
+
328
+ # build URL
329
+ params = { :address => query, :sensor => "false" }
330
+ url = "http://maps.google.com/maps/api/geocode/json?" + params.to_query
331
+
332
+ # query geocoder and make sure it responds quickly
339
333
  begin
340
334
  resp = nil
341
335
  timeout(3) do
@@ -345,24 +339,13 @@ module Geocoder
345
339
  return nil
346
340
  end
347
341
  end
348
-
349
- ##
350
- # Name of the ActiveRecord scope method.
351
- #
352
- def self.scope_method_name
353
- begin
354
- Rails.version.starts_with?("3") ? :scope : :named_scope
355
- rescue NameError
356
- :named_scope
357
- end
358
- end
359
342
  end
360
343
 
361
344
  ##
362
345
  # Add geocoded_by method to ActiveRecord::Base so Geocoder is accessible.
363
346
  #
364
347
  ActiveRecord::Base.class_eval do
365
-
348
+
366
349
  ##
367
350
  # Set attribute names and include the Geocoder module.
368
351
  #
@@ -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.4"
8
+ s.version = "0.9.5"
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-08-02}
12
+ s.date = %q{2010-10-15}
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 = [
@@ -28,25 +28,25 @@ Gem::Specification.new do |s|
28
28
  "lib/geocoder.rb",
29
29
  "lib/tasks/geocoder_tasks.rake",
30
30
  "rails-geocoder.gemspec",
31
- "test/fixtures/madison_square_garden.xml",
31
+ "test/fixtures/madison_square_garden.json",
32
32
  "test/geocoder_test.rb",
33
33
  "test/test_helper.rb"
34
34
  ]
35
35
  s.homepage = %q{http://github.com/alexreisner/geocoder}
36
36
  s.rdoc_options = ["--charset=UTF-8"]
37
37
  s.require_paths = ["lib"]
38
- s.rubygems_version = %q{1.3.6}
38
+ s.rubygems_version = %q{1.3.7}
39
39
  s.summary = %q{Add geocoding functionality to Rails models.}
40
40
  s.test_files = [
41
- "test/geocoder_test.rb",
42
- "test/test_helper.rb"
41
+ "test/test_helper.rb",
42
+ "test/geocoder_test.rb"
43
43
  ]
44
44
 
45
45
  if s.respond_to? :specification_version then
46
46
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
47
47
  s.specification_version = 3
48
48
 
49
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
49
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
50
  else
51
51
  end
52
52
  else
@@ -0,0 +1,57 @@
1
+ {
2
+ "status": "OK",
3
+ "results": [ {
4
+ "types": [ "street_address" ],
5
+ "formatted_address": "4 Penn Plaza, New York, NY 10001, USA",
6
+ "address_components": [ {
7
+ "long_name": "4",
8
+ "short_name": "4",
9
+ "types": [ "street_number" ]
10
+ }, {
11
+ "long_name": "Penn Plaza",
12
+ "short_name": "Penn Plaza",
13
+ "types": [ "route" ]
14
+ }, {
15
+ "long_name": "Manhattan",
16
+ "short_name": "Manhattan",
17
+ "types": [ "sublocality", "political" ]
18
+ }, {
19
+ "long_name": "New York",
20
+ "short_name": "New York",
21
+ "types": [ "locality", "political" ]
22
+ }, {
23
+ "long_name": "New York",
24
+ "short_name": "New York",
25
+ "types": [ "administrative_area_level_2", "political" ]
26
+ }, {
27
+ "long_name": "New York",
28
+ "short_name": "NY",
29
+ "types": [ "administrative_area_level_1", "political" ]
30
+ }, {
31
+ "long_name": "United States",
32
+ "short_name": "US",
33
+ "types": [ "country", "political" ]
34
+ }, {
35
+ "long_name": "10001",
36
+ "short_name": "10001",
37
+ "types": [ "postal_code" ]
38
+ } ],
39
+ "geometry": {
40
+ "location": {
41
+ "lat": 40.7503540,
42
+ "lng": -73.9933710
43
+ },
44
+ "location_type": "ROOFTOP",
45
+ "viewport": {
46
+ "southwest": {
47
+ "lat": 40.7473324,
48
+ "lng": -73.9965316
49
+ },
50
+ "northeast": {
51
+ "lat": 40.7536276,
52
+ "lng": -73.9902364
53
+ }
54
+ }
55
+ }
56
+ } ]
57
+ }
@@ -7,12 +7,12 @@ class GeocoderTest < Test::Unit::TestCase
7
7
  assert_equal [40.750354, -73.993371], v.fetch_coordinates
8
8
  assert_equal [40.750354, -73.993371], [v.latitude, v.longitude]
9
9
  end
10
-
10
+
11
11
  # sanity check
12
12
  def test_distance_between
13
13
  assert_equal 69, Geocoder.distance_between(0,0, 0,1).round
14
14
  end
15
-
15
+
16
16
  # sanity check
17
17
  def test_geographic_center
18
18
  assert_equal [0.0, 0.5],
data/test/test_helper.rb CHANGED
@@ -10,24 +10,24 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
10
10
  #
11
11
  module ActiveRecord
12
12
  class Base
13
-
13
+
14
14
  def initialize
15
15
  @attributes = {}
16
16
  end
17
-
17
+
18
18
  def read_attribute(attr_name)
19
19
  @attributes[attr_name.to_sym]
20
20
  end
21
-
21
+
22
22
  def write_attribute(attr_name, value)
23
23
  @attributes[attr_name.to_sym] = value
24
24
  end
25
-
25
+
26
26
  def update_attribute(attr_name, value)
27
27
  write_attribute(attr_name.to_sym, value)
28
28
  end
29
-
30
- def self.named_scope(*args); end
29
+
30
+ def self.scope(*args); end
31
31
  end
32
32
  end
33
33
 
@@ -38,9 +38,8 @@ require 'geocoder'
38
38
  # Mock HTTP request to Google.
39
39
  #
40
40
  module Geocoder
41
- def self._fetch_xml(query)
42
- filename = File.join("test", "fixtures", "madison_square_garden.xml")
43
- File.read(filename)
41
+ def self._fetch_raw_response(query)
42
+ File.read(File.join("test", "fixtures", "madison_square_garden.json"))
44
43
  end
45
44
  end
46
45
 
@@ -49,13 +48,13 @@ end
49
48
  #
50
49
  class Venue < ActiveRecord::Base
51
50
  geocoded_by :address
52
-
51
+
53
52
  def initialize(name, address)
54
53
  super()
55
54
  write_attribute :name, name
56
55
  write_attribute :address, address
57
56
  end
58
-
57
+
59
58
  ##
60
59
  # If method not found, assume it's an ActiveRecord attribute reader.
61
60
  #
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-geocoder
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 49
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 9
8
- - 4
9
- version: 0.9.4
9
+ - 5
10
+ version: 0.9.5
10
11
  platform: ruby
11
12
  authors:
12
13
  - Alex Reisner
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-08-02 00:00:00 -04:00
18
+ date: 2010-10-15 00:00:00 -04:00
18
19
  default_executable:
19
20
  dependencies: []
20
21
 
@@ -39,7 +40,7 @@ files:
39
40
  - lib/geocoder.rb
40
41
  - lib/tasks/geocoder_tasks.rake
41
42
  - rails-geocoder.gemspec
42
- - test/fixtures/madison_square_garden.xml
43
+ - test/fixtures/madison_square_garden.json
43
44
  - test/geocoder_test.rb
44
45
  - test/test_helper.rb
45
46
  has_rdoc: true
@@ -52,26 +53,30 @@ rdoc_options:
52
53
  require_paths:
53
54
  - lib
54
55
  required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
55
57
  requirements:
56
58
  - - ">="
57
59
  - !ruby/object:Gem::Version
60
+ hash: 3
58
61
  segments:
59
62
  - 0
60
63
  version: "0"
61
64
  required_rubygems_version: !ruby/object:Gem::Requirement
65
+ none: false
62
66
  requirements:
63
67
  - - ">="
64
68
  - !ruby/object:Gem::Version
69
+ hash: 3
65
70
  segments:
66
71
  - 0
67
72
  version: "0"
68
73
  requirements: []
69
74
 
70
75
  rubyforge_project:
71
- rubygems_version: 1.3.6
76
+ rubygems_version: 1.3.7
72
77
  signing_key:
73
78
  specification_version: 3
74
79
  summary: Add geocoding functionality to Rails models.
75
80
  test_files:
76
- - test/geocoder_test.rb
77
81
  - test/test_helper.rb
82
+ - test/geocoder_test.rb
@@ -1,69 +0,0 @@
1
- <GeocodeResponse>
2
- <status>OK</status>
3
- <result>
4
- <type>street_address</type>
5
- <formatted_address>4 Penn Plaza, New York, NY 10001, USA</formatted_address>
6
- <address_component>
7
- <long_name>4</long_name>
8
- <short_name>4</short_name>
9
- <type>street_number</type>
10
- </address_component>
11
- <address_component>
12
- <long_name>Penn Plaza</long_name>
13
- <short_name>Penn Plaza</short_name>
14
- <type>route</type>
15
- </address_component>
16
- <address_component>
17
- <long_name>Manhattan</long_name>
18
- <short_name>Manhattan</short_name>
19
- <type>sublocality</type>
20
- <type>political</type>
21
- </address_component>
22
- <address_component>
23
- <long_name>New York</long_name>
24
- <short_name>New York</short_name>
25
- <type>locality</type>
26
- <type>political</type>
27
- </address_component>
28
- <address_component>
29
- <long_name>New York</long_name>
30
- <short_name>New York</short_name>
31
- <type>administrative_area_level_2</type>
32
- <type>political</type>
33
- </address_component>
34
- <address_component>
35
- <long_name>New York</long_name>
36
- <short_name>NY</short_name>
37
- <type>administrative_area_level_1</type>
38
- <type>political</type>
39
- </address_component>
40
- <address_component>
41
- <long_name>United States</long_name>
42
- <short_name>US</short_name>
43
- <type>country</type>
44
- <type>political</type>
45
- </address_component>
46
- <address_component>
47
- <long_name>10001</long_name>
48
- <short_name>10001</short_name>
49
- <type>postal_code</type>
50
- </address_component>
51
- <geometry>
52
- <location>
53
- <lat>40.7503540</lat>
54
- <lng>-73.9933710</lng>
55
- </location>
56
- <location_type>ROOFTOP</location_type>
57
- <viewport>
58
- <southwest>
59
- <lat>40.7473324</lat>
60
- <lng>-73.9965316</lng>
61
- </southwest>
62
- <northeast>
63
- <lat>40.7536276</lat>
64
- <lng>-73.9902364</lng>
65
- </northeast>
66
- </viewport>
67
- </geometry>
68
- </result>
69
- </GeocodeResponse>