A lot of applications out there use maps to show the locations of different objects. Maps are great for good user experience: user can actually see where an object lies in the map, drag it around different places, search different objects by drawing shapes on a map, and not to mention that the nearby search has one of the favorite features of using maps in your application. And the best thing is: maps aren’t hard to implement – not at least in Rails.
Rails is famous for its modular approach for different things. Either one can go, and write all the code for communicating with Google Maps API from scratch, but why to “reinvent the wheel” when there are so many gems available ready to do the task that you are trying to accomplish.
In this article, we shall study geocoder gem, a very popular gem to integrate geolocation in your application.
Don’t forget to do bundle install.
The very first thing that we need to is to add columns for storing the location of an object. Let’s say we have a model House and we would like to store the location of different House objects in the database.
rails g migration add_latitude_and_longitude_columns_to_hou ses longitude:float latitude:float
After that, we need to specify from where we need to get latitude and longitude. It won’t be a good user experience to get latitude and longitude values directly from the user – instead, we’d like to get a plain string from the user that represents the address, and get it converted to latitude and longitude from that address.
class House < ActiveRecord::Base
address is a column in houses table, responsible for storing the actual address of a house. after_validation will make sure that each time a House object is saved, it will update the latitude and longitude according to the address.
Google Maps has a limit of how many requests we can send per second and a total of how many a day. after_validation will work each time an object is saved, even when address has been same. So we’d like to work through this exception:
after_validation :geocode, if: :address_changed?
Now, it will only hit Google Maps API for getting latitude and longitude when address actually changed.
Now, there are a plenty of methods provided by geocoder that we can use to accomplish different tasks related to distance measurement.
Starting with near method. You can pass it two arguments: the location within which it should send you different objects, and the actual distance taken from that location.
House.near('Omaha, NE, US', 20)
The above line of code will send you different objects that are within a distance of 20 miles from ‘Omaha, NE, US’. Not only the address, you can also use latitude and longitude to perform the same operation:
House.near([40.71, -100.23], 20)
You can change the distance unit as well. If you want to use a different unit, other than mile, you will accomplish this by sending an option through the key units like:
House.near('Omaha, NE, US', 20, units: :km)
So this is it for the first part. Head over to the second part to know about advanced things in Google Maps.