Use Google Maps with Rails

Share this article

Maps are the way to navigate the world. They give the ability to inspect every single location on Earth, opening the way to services like routing and soil composition. In this article, I will go through the Google Maps API (and some alternatives) and integrate it with Rails.

Tutorial Source Repository

The source code is available on a Github repository. Each feature is a separate commit, so you can follow the tutorial progress using git checkout .


  • Basic knowledge of Ruby on Rails using RailsBricks.
  • Intermediate knowledge of JavaScript
  • How web maps work. This article is worth reading if you are new to the game.

Our goal is to make map integration with Rails simple. The tutorial goes through the exact steps to integrate Google Maps, covering some useful Rails gems. Finally, alternatives to Google Maps, like the popular open source libraries Leaflet.js and MapBox, will get a brief look.

Initializing the Map

In the past, Google Maps required an API key, however, this API key is no longer mandatory on V3. If you are using another version, follow these steps:

If you use Google Maps V3 just skip this part

  1. Go to the Google API console

  2. Click the APIs & auth -> APIs.

  3. Activate Google Maps JavaScript API v3 by clicking the Status button to be On.

  4. Click on credentials -> Create new key -> browser key

  5. Make sure that ACCEPT REQUESTS FROM THESE HTTP REFERERS (WEB SITES) is empty or contains your domain, as in the image below. Create a browser key and configure allowed referers

NOTE: Not every aspect of the map is covered in the material below. For more detailed information, you can visit the Google Maps JavaScript documentation.

Loading the Map

At first, create the project with RailsBrick (You’re free to use any tool for building rails apps). It’s a rails app creator with basic functionality out of the box. You can get how to use it from the introductionary video here.

To initialize the map in our home page, create a div with an id of map-canvas in the home view (/app/views/home.erb). Wrap this div in another with an id of map-container, which will be used to add some styling to the map.

First: Here is the code of the home view:

<% title("Home Page") %>
<h1>Google Maps Tut</h1>
<div id="map-container">
  <div id="map-canvas"></div>

Add some CSS. Open up the file named frameworkandoverrides.css.scss, which is a part of the RailsBricks boilerplate and is used to override Bootstrap styles.

Second: Add the following styles:

#map-container {
   height: 400px;
   border-radius: 16px 16px;
   border-color: #fff;
   border-style: solid;
   box-shadow: 2px 2px 10px #B1B1B1;
   margin-top: 25px;
   border-width: 7px;
 #map-canvas {
   height: 384px;
   width: 100%;

As you can see in the above CSS, we set the map-container to a fixed height of 400 pixels and added some border styling. The last step to get an initial working map is to create a folder named “map” in app/assets/javascript/map and add a file named gmap.js. Now the map should look like this:

Initializing the map

NOTE: If the map zoom controller doesn’t show properly, it’s a conflict with Bootstrap styling for images and labels. Just add the following overrides to your CSS (frameworkandoverrides.css.scss) file:

/* Bootstrap Css Map Fix*/
#map-container #map-canvas img {
  max-width: none;
/* Bootstrap Css Map Fix*/
#map-container #map-canvas label {
  width: auto; display:inline;

Drawing on the Map

Basic markers

The Google Maps API contains a marker object allowing you to easily create simple markers. The Marker object contains attributes like marker position, marker title, and the map where the marker is located.

To avoid repeating the code, create a function called createMarker with the parameters coords, map, and title:

var marker;
function createMarker(coords, map, title){
  marker = new google.maps.Marker({
    position: coords,
    map: map,
    title: title

Custom Markers

The Marker object has an “icon” attribute which can take a path or image object. We will create two functions: one for creating an image and the one for creating a custom marker. To make the marker draggable, simply add the attribute draggable with the value true. Also, the Google Maps API supports two types of animation for the marker: DROP and BOUNCE.

Create a function named createImage which will return the image object used by our custom marker. Its size is 32×32 pixels and its origin is (0, 0).

function createImage(url){
  var image = {
    url: url,
    // This marker is 32 pixels wide by 32 pixels tall.
    size: new google.maps.Size(32, 32),
    // The origin for this image is 0,0.
    origin: new google.maps.Point(0,0),
    // The anchor for this image is the base of the flagpole at 0,32.
    anchor: new google.maps.Point(0, 32)
  return image;

Next, create a function called createCustomMarker to do the actual work of creating the marker object. It takes the coords, the map object, and the title for the marker. Use the function createImage to return the correct image for our icon.

function createCustomMarker(coords,map,title){
  marker = new google.maps.Marker({
    position: coords,
    map: map,
    title: title,
    icon: createImage("/assets/icon.png")


Infowindow is a tooltip for displaying content (text or images). You can add an infowindow to a marker or on a specified longitude and latitude (lon, and lat for short). The InfoWindow object takes a InfoWindowOptions object.

function createInfoWindow(text){
  var infowindow = new google.maps.InfoWindow({
    content: text
  return infowindow;

Put the following code in an initialize() function

// add infowindow when clicking on the simple marker marker
var info = createInfoWindow("Congratulations!");
google.maps.event.addListener(marker, 'click', function() {,marker);

This code will create an Infowindow named info and place the text “Congratulations!” in it. An event listener handles the click event on the marker to open the Infowindow.

Drawing simple and custom marker

Drawing lines

Drawing lines requires a series of coordinates to connect. The Google Maps API provides an object called Polyline for drawing lines with attributes stroke_color, weight, and opacity, along with adding icons, symbols, or animation.

Simple Line

// drawing static polyline
var lineCoordinates = [
  new google.maps.LatLng(30.055487, 31.279766),
  new google.maps.LatLng(30.223356, 31.324345),
  new google.maps.LatLng(30.345656, 31.567677),
  new google.maps.LatLng(30.565678, 31.676887)
createPolyline(map, lineCoordinates, lineSymbol);

var linePath;
function createPolyline(map,lineCoordinates,lineSymbol){
  linePath = new google.maps.Polyline({
    path: lineCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: 1.0,
    strokeWeight: 2

We define an array called lineCoordinates with the coords for the polyline. The function createPolyline actually creates the polyline, setting its path using the lineCoordinates array. The geodesic attribute is true, telling Google Maps to take care of the complicated math for us. Give it a stroke color of #FF0000, an opacity of 1, and a stroke weight of 2 to make it visible. After we have our polyline object ready, add it to the map using the setMap function.

Simple Line with Dashes.

Drawing a dashed line is simply a matter of creating the style and telling the line to use it. Below, the lineSymbol variable is added to the polyline. Notice that the lineSymbol has a path to follow and a scale of 4. The createPolyline function is modified to use lineSymbol as a repeated icon.

var lineSymbol = {
  path: 'M 0,-1 0,1',
  scale: 4,
  strokeOpacity: 1,
  strokeColor: '#393'

// modify the createPolyline function to contain the symbol
var linePath;
function createPolyline(map, lineCoordinates, lineSymbol){
  linePath = new google.maps.Polyline({
    path: lineCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: 1.0,
    strokeWeight: 2,
     icons: [{ // this Array is for adding symbols to the line
      icon: lineSymbol,
      offset: '100%'

Animated Dashes

We can even animate the dashes by adding a function called animateCircle that moves the icons along the line by changing the offset. There isn’t even a need to change the createPolyline function.

function animateCircle() {
  var count = 0;
  window.setInterval(function() {
    count = (count + 1) % 200;

    var icons = linePath.get('icons');
    icons[0].offset = (count / 2) + '%';
    linePath.set('icons', icons);
  }, 20);

//modify the `createPolyline` function to be like the following
var linePath;
function createPolyline(map, lineCoordinates, lineSymbol){
  linePath = new google.maps.Polyline({
    path: lineCoordinates,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: 1.0,
    strokeWeight: 2,
     icons: [{ // this Array is for adding symbols to the line
      icon: lineSymbol,
      offset: '0',
      repeat: '20px'

Then call the animateCircle() function after creating the polyline with createPolyline function.

User-Created Dynamic Polyline

In the following code, we add the polyline options/attributes to a variable and use it to create the polyline. This is not very different from the above code samples. Adding a click event listener to the map that adds a point to our line allows the user to draw at will.

// drawing dynamic polyline
var polyOptions = {
  strokeColor: '#000000',
  strokeOpacity: 1.0,
  strokeWeight: 3
poly = new google.maps.Polyline(polyOptions);
google.maps.event.addListener(map, 'click', addLatLng);

function addLatLng(event){
  var path = poly.getPath();
  // Because path is an MVCArray, we can simply append a new coordinate
  // and it will automatically appear.

Drawing simple and animated lines

Drawing Polygons

Polygons are similar to polylines in that they are drawn by a series of coordinates. A Polygon has a stroke and fill, which can be customized. We will add the coords for the polygon by hand in an array called polygonCoords and pass it to a new function named drawingPolygon. This function creates the polygon and set its paths to the coords added in the polygonCoords array. Polygons are also draggable and editable.

Simple Polygon

// drawing polygon
var polygonCoords = [
  new google.maps.LatLng(30.055487, 31.279766),
  new google.maps.LatLng(30.466465, 31.118292),
  new google.maps.LatLng(30.321384, 31.75737),
  new google.maps.LatLng(30.055487, 31.279766)

// Construct the polygon.

function drawingPolygon(polygonCoords) {
  var polygon = new google.maps.Polygon({
    paths: polygonCoords,
    strokeColor: '#FF00FF',
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: '#FF0000',
    fillOpacity: 0.35,
    editable: true

Drawing polygon

Drawing on the Map Using Drawing library

The Google Maps API supports a drawing library that provides a graphical interface. This GUI lets users draw polylines, polygons, circles, markers, and triangles on the map.

To load the drawing library on the map, just make the maps API URL include &libraries=drawing and start using the DrawingManager object.

The API source link should look like this:

Initialize the DrawingManager object:

// trying the drawing liberary
var drawingManager = new google.maps.drawing.DrawingManager({
  drawingMode: null,
  drawingControl: true,
  drawingControlOptions: {
    position: google.maps.ControlPosition.TOP_CENTER,
    drawingModes: [
  markerOptions: {
    icon: "/assets/icon.png"

The DrawingManager constructor allows you to manage the map drawing tools (controls) by specifying which overlay will be rendered, its position on the map, and its initial state. Setting drawingMode to null means it will not be defaulted to a specific overlay control. It can be defaulted with the polyline overlay by changing null to google.maps.drawing.OverlayType.POLYLINE.

The second argument is drawingControl which takes true for rendering the control or false for hiding it. drawingControlOptions specifies the control position on the map. Google Maps provides various places to put its controls, such as TOP_CENTER, TOP_RIGHT, BOTTOM_LEFT, and so on.

The arguments also specify the available drawingModes, an array of available google.maps.drawing.OverlayType constants like CIRCLE, POLYLINE, POLYGONS, RECTANGLE, MARKER. You can also give each overlay specific properties, just like we did in the previous code snippets.

The last step is to set the map on drawingManager.

Drawing markers, polylines, polygons, circles and triangles by Drawing library

Adding Map Services

Geocoding and Reverse Geocoding

The Google Maps API provides a class called Geocoder for getting coordinate locations of known addresses (geocoding) and vice-versa (reverse geocoding) dynamically.

While the service no longer requires an API key, it does limit geocodes to 2,500 per day and requires that the resulting application show data with a Google Map. The returned data is either JSON or XML.

var geocoding  = new google.maps.Geocoder();

Get Coordinates by Geocoding

Here, we get the coordinates by entering an address into an input field.

function codeAddress(geocoding){
  var address = $("#search_box_geocoding").val();
  if(address.length > 0){
    geocoding.geocode({'address': address},function(results, status){
      if(status == google.maps.GeocoderStatus.OK){
        var marker = new google.maps.Marker({
          map: map,
          position: results[0].geometry.location
      } else {
        alert("Geocode was not successful for the following reason: " + status);
  } else {
    alert("Search field can't be blank");


Get Address by Reverse Geocoding

In this case, we pass the latlng variable to the geocode object to generate the location (address) on the map.

function codeLatLng(geocoding) {
  var input = $('#search_box_reverse').val();

  var latlngbounds = new google.maps.LatLngBounds();
  var listener;
  var regex = /([1-9])+\.([1-9])+\,([1-9])+\.([1-9])+/g;
  if(regex.test(input)) {
    var latLngStr = input.split(",",2);
    var lat = parseFloat(latLngStr[0]);
    var lng = parseFloat(latLngStr[1]);
    var latLng = new google.maps.LatLng(lat, lng);
    geocoding.geocode({'latLng': latLng}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        if(results.length > 0) {
          var marker;
          var i;
          info = createInfoWindow("");
          for(i in results){
              marker = new google.maps.Marker({
              map: map,
              position: results[i].geometry.location

            google.maps.event.addListener(marker, 'click', (function(marker,i) {
              return function() {

          listener = google.maps.event.addListener(map, "idle", function() {
            if (map.getZoom() > 16) map.setZoom(16);
      } else {
        alert("Geocoder failed due to: " + status);
  } else {
    alert("Wrong lat,lng format!");

Reverse Geocoding

Generating Directions

The Google Map API provides a great direction service for calculating routes between two or more addresses. This service can be enabled by initializing google.maps.DirectionsService, which takes no parameters but has one method called route(). This method takes two parameters: an object from google.maps.DirectionsRequest and a callback function.

The basic properties of DirectionRequest are origin, destination, and the travelMode that defines the mode of transportation. DirectionsStatus contains the repsonse status for the directions request.

To expose the resulting routes, there is DirectionsRenderer, which takes no parameters and has a method called setMap for defining the map and a method called setDirections that sets the returned response.

For more details about the directions service, read this tutorial

var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();

map = new google.maps.Map(document.getElementById("map-canvas"),mapOptions);


var request = {
  origin: "Mansoura, Daqahlia, Egypt",
  destination: "Cairo, Egypt",
  travelMode: google.maps.DirectionsTravelMode.DRIVING
directionsService.route(request, function(response, status) {
  //Check if request is successful.
  if (status == google.maps.DirectionsStatus.OK) {
    directionsDisplay.setDirections(response); //Display the directions result

Direction between Cairo and Manousoura cities

Map Controls

Google Maps provides controls on the map for handling and manipulating the map UI. These controls can be disabled, moved, or even customized with new functionality.

The available controls are:

  • Zoom control
  • Pan control
  • Scale control
  • MapType control
  • Streetview control
  • Rotate control
  • Overview map control

The default UI controls can be disabled by adding disableDefaultUI: true to the map options.

To remove one of the default controls, add it as an attribute on the MapOptions, like panControl: true, zoomControl: false.

var mapOptions = {
  center: new google.maps.LatLng(30.055487, 31.279766),
  zoom: 8,
  mapTypeId: google.maps.MapTypeId.NORMAL,
  panControl: true,
  zoomControlOptions: {
    style: google.maps.ZoomControlStyle.SMALL,
    position: google.maps.ControlPosition.LEFT_CENTER
  mapTypeControlOptions: {
    style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
    mapTypeIds: [google.maps.MapTypeId.ROADMAP, "map_style"]
  scaleControl: false,
  streetViewControl: true,
  overviewMapControl: true

Simple and Custom controls (fullscreen,zoom)

Custom Map Styles

This feature give the ability to manipulate the standard base map presentation UI.

Map presentation is composed of two characteristics: Map features lie roads, park, mountains, etc. and Styles for various map elements.

Gotcha: The style array has a limited number of characters allowed which, if exceeded, prevents the style from being applied to the map.

To create a custom map style, do the following:

First: Create the style array with two basic properties MapFeatures and stylers:

var mapstyle = [
    "featureType": "administrative.locality",
    "elementType": "labels.icon",
    "stylers": [
      { "invert_lightness": true },
      { "color": "#e40952" },
      { "visibility": "on" }
    "featureType": "water",
    "elementType": "geometry.fill",
    "stylers": [
      { "visibility": "on" },
      { "hue": "#5eff00" },
      { "color": "#282744" },
      { "weight": 0.1 },
      { "saturation": -56 },
      { "lightness": 22 },
      { "gamma": 3.91 }

Second: Set the mapTypeId in the map options:

var mapOptions = {
  center: new google.maps.LatLng(30.055487, 31.279766),
  zoom: 8,
  mapTypeId: google.maps.MapTypeId.NORMAL,
  mapTypeControlOptions: {
    style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
    mapTypeIds: [google.maps.MapTypeId.ROADMAP, "map_style"]

Third: Instantiate the StyledMapType, providing the pre-defined mapstyle array and the map name. The name will appear in the control as a style option.

var styledMap = new google.maps.StyledMapType(mapstyle, {name: "styled map"});
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);

Fourth: Add our customized map style to the map’s mapTypes:

map.mapTypes.set("map_style", styledMap);

Fifth: Set the mapType ID to our styled map:


Giving Custom style to the map

Useful Rails Gems


The Geocoder gem provides geocoding, reverse gecoding, finding nearby locations, determining distances, and map services for Ruby.

NOTE: Geocoder supports using rails3 and rails4, there’s another branch for rails2.

Geocoder is installed like any Ruby gem using gem install geocoder or adding gem "geocoder" to the Gemfile and running bundle install.

You have to add two float fields (lat, lng) to any model used to store latitude and longitude values after fetching them by street address or zip codes like so:

rails generate migration AddLatitudeAndLongitudeToModel lat:float lng:float
rake db:migrate

Also, add the following to the model to specify which service will be used (geocoder or reverse geocoder):

geocoded_by :address
# auto-fetch coordinates and the condition is for preventing fetching the same address more than once
after_validation :geocode, if: :address_changed?

This full_street_address needs to be implemented on the model to create a readable address.

NOTE: Geocoder supports some of the popular databases like (MySQL, PostgreSQL, MongoDB).

The Geocoder also gem provides you with an easy way to swap between various geocoding providers.


GMaps4rails is an awesome gem that provides geocoding and map locations. It uses JS to generate filters when rendering markers. It also has a geocoding feature that calculates simple lat, lng values.

You can combine this gem with the Geocoder gem features, rendering the results on the map using GMaps4rails.


First: Add the following line to your Gemfile file:

gem 'gmaps4rails

Then run bundle install

Second: Add a div to hold the map:

<div style='width: 800px;'>
  <div id="map" style='width: 800px; height: 400px;'></div>

Third: Add the Google scripts to your application.html.erb layout:

<script src="//" type="text/javascript"></script>
<script src='//' type='text/javascript'></script>

Fourth: Require the underscore.js library too, because Gmaps4rails uses it. In your Rails application.js:

//= require underscore
//= require gmaps/google

Now, create the map as follows:

handler ='Google');
    provider: {
      disableDefaultUI: true
      // here you can pass other Google Maps API options here
    internal: {
      id: 'map'
  function() {
    markers = handler.addMarkers([
        "lat": 0,
        "lng": 0,
        "picture": {
          "url": "",
          "width":  36,
          "height": 36
        "infowindow": "hello!"

For more details about this gem, check this link.

Alternatives to Google Maps


Leaflet is a modern JavaScript library for embedding maps which gained its popularity from simplicity and ease of implementing markers, overlays, and manipulating various map components. Leaflet can be extended with the enormous set of available plugins. It uses a permissive BSD open-source license, so it can be added to any site without legal issues. Also, it supports multiple map providers, including OpenStreetMap, MapQuestOpen, Stamen, Esri, and OpenWeatherMap.


Download it from its official site It is available as a .zip file or a fork on github.

A snip of code to illustrate Leaflet’s simplicity:

// create a map in the "map" div, set the view to a given place and zoom
var map ='map').setView([51.505, -0.09], 13);

// add an OpenStreetMap tile layer
L.tileLayer('http://{s}{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="">OpenStreetMap</a> contributors'

// add a marker in the given location, attach some popup content to it and open the popup
L.marker([51.5, -0.09]).addTo(map)
    .bindPopup('A pretty CSS3 popup. <br> Easily customizable.')

Check the Leaflet quick start for more information.


MapBox is a beautiful tool which gives flexibility for creating maps. It has the ability to design custom maps with wonderful layers and a lot of custom features with TileMill (map design studio), a downloadabale application. Or you can create MapBox web applications with custom markers and overlays by using its JavaScript API.


All you need is an account on MapBox. Once you’ve created some maps on MapBox, those Map IDs are used to integrate it with your web application.

This example will give you just a glance about using MapBox with JavaScript.

After creating your map on MapBox, include the Mapbox.js library on your project.

First: Initialize the map:

var map ='map');

Second: Set the zoom range and center zoom point of the map:

map.setZoomRange(5, 15);

    lat: 37.871385,
    lon: -99.228516
}, 5);

Third: Add the custom layer you created on MapBox.


After that, you can embed more features in the map, like markers, UI features (fullscreen, zoomer) and so on.

NOTE: This is not an in-depth tutorial on how to use MapBox, but it exposes it as an alternative option to Google Maps.


This tutorial gives a basic understanding of how to create maps and general map concepts. Hopefully, you can now create a map to meet your needs using any map API you choose.

Frequently Asked Questions (FAQs) about Using Google Maps with Rails

How Can I Customize the Appearance of My Google Map in Rails?

Customizing the appearance of your Google Map in Rails can be achieved using the Google Maps Styling Wizard. This tool allows you to change the color scheme, visibility of features, and more. After customizing, you can export the JSON style array and integrate it into your Rails application. Remember to replace the default style in your map initialization code with your custom style.

How Can I Add Multiple Markers to My Google Map in Rails?

Adding multiple markers can be done by iterating over an array of coordinates in your Rails application. Each coordinate pair can be used to create a new marker and add it to the map. This can be particularly useful when displaying multiple locations or points of interest on your map.

How Can I Use Google Maps API with Rails?

To use Google Maps API with Rails, you need to first obtain an API key from the Google Cloud Platform Console. Once you have the key, you can include the Google Maps JavaScript API in your application.js file. You can then use the API to create maps, add markers, and implement other map features.

How Can I Integrate Snazzy Maps with Rails?

Snazzy Maps offers a collection of customizable map themes for Google Maps. To integrate a Snazzy Map theme with Rails, you need to choose a theme from the Snazzy Maps website, copy the JavaScript style array, and replace the default style in your map initialization code with the Snazzy Map style.

How Can I Use the Google-Maps-for-Rails Gem?

The Google-Maps-for-Rails (Gmaps4rails) gem simplifies the process of integrating Google Maps with Rails. After installing the gem, you can use it to create maps, add markers, and implement other map features. The gem also supports multiple map providers and includes a variety of customization options.

How Can I Use Google Maps Cloud-Based Map Styling in Rails?

Google Maps Cloud-Based Map Styling allows you to create custom map styles that are stored in the cloud and can be applied to any map in your Rails application. To use this feature, you need to create a map style in the Google Cloud Console, obtain the map ID, and use this ID when initializing your map.

How Can I Display a User’s Current Location on a Google Map in Rails?

Displaying a user’s current location can be achieved using the Geolocation API. This API can obtain the user’s current coordinates, which can then be used to create a marker and center the map on the user’s location. Remember to handle the case where the user denies location access.

How Can I Implement Google Maps Directions in Rails?

Google Maps Directions can be implemented using the Directions API. This API allows you to calculate directions between locations, which can then be displayed on your map. You can customize the directions based on various factors, such as travel mode and waypoints.

How Can I Handle Errors When Using Google Maps API with Rails?

Handling errors is an important part of using the Google Maps API. The API includes various error codes that can help you diagnose and handle problems. For example, if you receive an INVALID_REQUEST error, it means that the request was malformed or missing required parameters.

How Can I Optimize the Performance of Google Maps in Rails?

Optimizing the performance of Google Maps in Rails can be achieved in several ways. For example, you can limit the number of markers displayed on the map, use marker clustering to group nearby markers, and disable unnecessary map features. Additionally, you can use the Lazy Load technique to load the map only when it’s needed.

Nouran MahmoudNouran Mahmoud
View Author

Passionate web wizard focusing on web development using RoR and JS technologies, an all-round geek who loves reading and writing in technology, she is graduated from the faculty of Computers and Information Science, with Java and web development experience. She currently works as a Front-end Engineer at

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week
Loading form