DEV Community

Nathan Chung
Nathan Chung

Posted on • Edited on

How to use Geocoder

You're working on your Rails project and you've saved all the addresses. Great!
What do you do now? If you're using the Google API and need to generate markers, you'll need latitude and longitude coordinates.

Geocoder is an amazing gem that takes an address and finds its latitude/longitude coordinates! It can also do it the opposite way as well. Saving the info in the backend can also reduce the API requests you've done in total.

How do you install it?

First, my original model looked like this:

class Activity < ApplicationRecord
  has_many :user_activities
  has_many :users, through: :user_activities
  has_many :comments
end

Now, we want to do two things:

gem install geocoder

then run
bundle install

We've now installed the gemfile and can start using the geocoder.

rails g migration AddLatitudeAndLongitudeToModel latitude:float longitude:float

It will create a migration file within your db/migrate folder

Run db:migrate and make sure it migrates successfully!

Now we're going to make a few additions to our Activity Model.

class Activity < ApplicationRecord
  geocoded_by :complete_address
  def complete_address
    [address, city, state, zipcode].compact.join(', ')
  end

  has_many :user_activities
  has_many :users, through: :user_activities
  has_many :comments
end

We've added geocoded_by :complete_address and also have defined what the complete_address is.

def complete_address
    [address, city, state, zipcode].compact.join(', ')
end

To verify if this is working, we can call
Activity.first.complete_address and if everything worked successfully, you'll be returned your new, complete address. This takes the data from the model and creates a full address.

From here we can call something like this:
Activity.last.geocode
and it will query geocode along with an API and return the coordinates.

Now, to limit requests we make every time our activities are queried we can do an after_validation like this:

class Activity < ApplicationRecord
  geocoded_by :complete_address
  after_validation :geocode, if: ->(obj) { obj.address.present? and obj.address_changed? }
  def complete_address
    [address, city, state, zipcode].compact.join(', ')
  end

  has_many :user_activities
  has_many :users, through: :user_activities
  has_many :comments
end

There you go. I hope you find what you're looking for. ;)

Top comments (0)