Google Place Autocomplete on Ruby on Rails

The principle consists in parsing and injecting the fields of your database (locality, administrative region, postal code, etc…) from the address. The user chooses his address from the suggested list.

That’s what we’re going to get !

autocomplete in action

Google Place Autocomplete: Creating Google API Keys

We will use Geocoder which uses Google’s geolocation API. You will be entitled to a number of free requests.

To know the prices, click HERE

You will need to enable Google Maps Javascript API and Google Places Web API service.

Log in to Google API Console and create a new project.

Google place autocomplete : Create new project

Search for the Maps Javascript API library and enable it.

Google place autocomplete : Activate Maps Javascript API

Create the credentials associated with this API.

APi Credentials

This server key will be added later in this tutorial in our Ruby on Rails project

API key created

Once you have added the key, you can name it, here Geocoding Server key.

API key with any restrict yet

Search for and enable the Places API Web Service library.

Google place autocomplete : activate Places API

Click on the Credentials Icon, select settings on API keys name and on RESTRICT KEY.

Geocoding server key naming

Check the http restriction, enter a restriction in localhost:3000/* and for your heroku repository <YourProjectName>.herokuapp.com.

To finish, click on Save.

Your key is operational

API key with restrict

Google place Autocomplete: here we go !

Create a new project with the name of your choice, here “Google_place_autocomplete” specifying the use of a PostgreSQL database. The scaffold will generate the basic functions of the CRUD (Create Read Update Delete) and serve us for the demo.

$ rails new google_place_autocomplete -d postgresql
$ cd google_place_autocomplete
$ rails generate scaffold Autocomplete address:string street_number:integer locality:string route:string administrative_area_level_1:string country:string postal_code:integer
$ git init
$ git add .
$ git commit -m "First commit"
$ hub create
$ git push origin master
$ rails db:create && rails db:migrate 

Access the google_place_autocomplete directory from your code editor. In my case, I access it from sublime text by entering subl . from the console and open routes.rb with CTRL+P.

# app/config/routes.rb 
Rails.application.routes.draw do
 resources :autocompletes
 root to: 'autocompletes#new'
end 

Add to your Gemfile the gems “geocoder“, “figaro” and “jquery-rails“.

# gemfile
# [...]
gem "geocoder"
gem "figaro"
gem 'jquery-rails' 
# [...]

Perform the installation using the bundle install command from the command prompt.

$ bundle install
$ rails generate geocoder:config
$ bundle exec figaro install

Ajoutez jquery à votre application.js.

// app/assets/javascripts/application.js
//= require jquery
//= require rails-ujs
//= require turbolinks
//= require_tree .

Open the file geocoder.rb.

# config/initializers/geocoder.rb
Geocoder.configure(
   lookup:    :google,
   api_key:   ENV['GOOGLE_API_SERVER_KEY'],
   use_https: true,
   # [...]
) 

Update the javascript_include_tag from application.html.erb application.

# app/views/layouts/application.html.erb
# [...]
<%= javascript_include_tag "https://maps.googleapis.com/maps/api/js?libraries=places&key=#{ENV['GOOGLE_API_SERVER_KEY']}" %>
</head>
<body>
 <%= yield %>
 <%= javascript_include_tag 'application' %>
</body> 

Add your Google API keys to your application.yml.

# config/application.yml
GOOGLE_API_SERVER_KEY: "AIzaSyCayfEXhAAMxm5EzumWpnJcMLOI_TfXm-I"

Finally, create the autocomplete.js file and add the javascript code below.

# app/assets/javascripts/autocomplete.js
$(document).on('turbolinks:load', function() {
function initializeAutocomplete(id) {     
     var element = document.getElementById(id);
     if (element) {
       var autocomplete = new google.maps.places.Autocomplete(element, { types: ['geocode'], componentRestrictions: {country: 'us'} });
       google.maps.event.addListener(autocomplete, 'place_changed', onPlaceChanged);
       }
}

function onPlaceChanged() {
     var place = this.getPlace();     

     // console.log(place);  // Uncomment this line to view the full object returned by Google API.     

for (var i in place.address_components) {
 var component = place.address_components[i];
 for (var j in component.types) {  // Some types are ["country", "political"]
  var type_element = document.getElementById(component.types[j]);
  if (type_element) {
   type_element.value = component.long_name;
   }
  }
 }
}   
google.maps.event.addDomListener(window, 'load', function() {
 initializeAutocomplete('autocomplete_address');   
 }); 
}); 

by adding componentRestrictions: {country:’us’ } we limit the search to the United States

To go further in limiting the search click HERE

Change the id of the fields in your form as below to allow auto-completion once the address has been entered.

# app/views/_form.html.erb
# [...]
<div class="field">
 <%= form.label 'Adress' %>
 <%= form.text_field :address, placeholder: "Enter your adress", id: :autocomplete_address %>
</div>

<div class="field">
 <%= form.label 'Channel number' %>
 <%= form.number_field :street_number, id: :street_number %>
</div>

<div class="field">
 <%= form.label 'Town' %>
 <%= form.text_field :locality, id: :locality %>
</div>
 
<div class="field">
 <%= form.label 'Name of the channel' %>
 <%= form.text_field :route, id: :route %>
</div>

<div class="field">
 <%= form.label 'Area' %>
 <%= form.text_field :administrative_area_level_1, id: :administrative_area_level_1 %>
</div>

<div class="field">
 <%= form.label 'Country' %>
 <%= form.text_field :country, id: :country %>
</div>

<div class="field">
 <%= form.label 'Postal code' %>
 <%= form.number_field :postal_code, id: :postal_code %>
</div>
# [...] 

A form with style !

For design hardware, rather than using Bootstrap, we will use Materialize

Add to your Gemfile the gem materialize-sass.

# gemfile
gem 'materialize-sass', '~> 1.0.0'

Install the gem from your command prompt.

$ bundle install

Delete the application.css file from app/assets/stylesheets/application.css and create the application.scss file to import materialize styles.

# app/assets/stylesheets/application.scss 
@import "materialize"; 
@import "materialize/components/color-variables";
$primary-color: color("blue", "lighten-2") !default;
$secondary-color: color("yellow", "base") !default;
@import 'materialize'; 

We will center all the elements of our page using the Flexbox system

Following your application.scss add the scss style below to center the elements.

# app/assets/stylesheets/application.scss
# [...]
.flexbox {
   display: flex;
   flex-direction: column;
   align-items: center;
   justify-content: center;   
   .actions {
      text-align: center;
      margin-top: 20px;
   }
} 

Add the .flexbox tag to the new.html.erb view.

# app/views/autocompletes/new.html.erb 
<div class="flexbox">
<h1>New Autocomplete</h1>
<%= render 'form', autocomplete: @autocomplete %>
<%= link_to 'Back', autocompletes_path %>
</div>

Modify the submit of your form for autocomplete.

# app/views/_form.html.erb
# [...]
<div class="actions">
 <div class="btn waves-effect waves-light">
  <%= form.submit "Submit" %>
 </div>
</div>
# [...] 

To see the result, click HERE

To see the sources, click HERE

signature Pierre-Christophe

No Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.