How to add geocode to an existing model in an existing app

Why geocode? Geocode gives you out of the box object geocoding (by street or IP address) and even reverse geocoding, this particular use is for Active Record and Rails, but it also works with Mongoid and other Rack frameworks such as Sinatra. It is not a server side best practice but in this case, my app is quite small, and I also like using it for beta app building. To showcase a product before plenty of developer hours get poured into it.

Geocoder will, in this case, be used to calculate nearby distances, and to be able to draw some pins on a map in the most natural possible way. This way blogging is made more comfortable for me. I like to maximize the effects of my pushing of pixels to affect all of my entries, and I try to keep the hardcoded parts to a minimum.


The installation is done in the same way a gem gets installed. In my case, I added it in the Gemfile inside my rails app. It looks like this:

#Geocode Gem
gem 'geocoder'

Then I updated my Gemfile.lock by running this command:

$ bundle update

Leveraging ActiveRecord in Rails

My Meeting model must have two new attributes, so I need to add two new columns in the database, Latitude, and Longitude they are both coordinates they are both floats and those are the default names for those attributes. This convention over configuration will make your life easier for a simple project, but the model configuration can also be changed. I won't edit it for now. This is the code that will create a migration for me to add those two columns to my Meeting model.

$ rails generate migration AddLatitudeAndLongitudeToMeeting latitude:float longitude:float
$ rake db:migrate

In the Model

Now the Model must be able to provide a method to generate the coordinates (Lat and Long). This is achieved by adding this in the Model.rb, in my case Meeting.rb will have this two new lines of code:

geocoded_by :full_street_address   # can also be an IP address
after_validation :geocode          # auto-fetch coordinates

To reverse geocode I would need to tell geocoder the attributes that store the coordinates

reverse_geocoded_by :latitude, :longitude
after_validation :reverse_geocode  # auto-fetch address

Sanity Check

After I have done this, I open the rails console and call on my model, to see what has changed. I also try to make sure that everything works the way I expect. My first approach is to check that all my routes still work, that I can still create my meetings the way I did before the geocode, that means I avoid committing any bugs to in my working branch. The server need to be close; I have to check I don't have any rogue servers too because the new methods won't be recognized since the server is running only with the previous gems.

After doing that, I can then create a new meeting and I when I added the location "NYC" my database entry now contained this two new fields, already calculated for me:

=> #<Meeting:0x007fafbcba1aa8
 latitude: 40.7127837,
 longitude: -74.0059413