Introduction

Sometimes it can be useful to find a user's physical location in our Rails application. For instance, maybe we want to send a special Happy Holidays to users of a particular country. IP address geolocation lets us do exactly that. With IP address geolocation you can get a pretty good idea of where the customer is accessing your site from as long as they aren't using a proxy server or some other means of obscuring their IP address. In this article we will show you how to utilize the Maxmind GeoIP database to look up the location of just about any IP address. Let's get started.

Heads Up! Please keep in mind that the GeoIP databases (especially the free ones) aren't totally and completely accurate, but they will generally give you a rough idea of where the user is located. Keep this in mind when designing any mission critical applications.

Rails Application Setup

To utilize the IP address geolocation functionality, we first need to add the geoip gem to our gemfile. Open up your gemfile and add in the code listed below.

Gemfile:

gem 'geoip', '~> 1.4.0'

Great, now let's run a bundle install to install the gem.

Terminal Commands:

bundle install

Now we need to download the GeoIP database for use with the geoip gem. A free one can be downloaded at this link, or you can use the paid version if you have a subscription. Once downloaded, extract the compressed archive and place the .dat folder contained within in the root directory of your Rails app.

Great, now let's create a controller so that we can play around with the GeoIP functionality. Run the commands below to create a controller called GeoIpRequest.

Terminal Commands:

rails g controller geo_ip_request new create

Next, open up your routes file and modify it so that it looks like the code listed below.

config/routes.rb:

Rails.application.routes.draw do
  resource :geo_ip_request, controller: :geo_ip_request

  root to: "geo_ip_request#new"
end

Great, now open up your GeoIpRequest controller and modify it so that it looks like the code listed below.

app/controllers/geo_ip_request_controller.rb:

class GeoIpRequestController < ApplicationController
  def new
  end

  def create
    require 'geoip'
    @info = GeoIP.new(Rails.root.join("GeoLiteCity.dat")).city(ip_request_params[:host])
  end

private
  def ip_request_params
    params.require(:request).permit(:host)
  end
end

In the code above, we tell the geoip gem to load our database file and do a search for the host parameter.

Now let's create our views. Open up the new view for the GeoIpRequest controller and modify it so that it looks like the code listed below.

app/views/geo_ip_request/new.html.erb:

<h1>GeoIP Example</h1>
<p>Get the country for any ip address or hostname by typing it below and pressing the lookup button.</p>

<%= form_for :request, url: geo_ip_request_index_path do |f| %>
  <%= f.text_field :host %>
  <%= f.submit "Lookup" %>
<% end %>

Great, now finally let's do the create view. Open up the create view for the GeoIpRequest controller and modify it so that it looks like the code listed below.

app/views/geo_ip_request/create.html.erb:

<h1>IP Address Info</h1>
<b>IP:&nbsp;&nbsp;</b><%= @info.request %><br />
<b>Country:&nbsp;&nbsp;</b><%= @info.country_name %><br />
<b>City:&nbsp;&nbsp;</b><%= @info.city_name %><br />
<b>Region:&nbsp;&nbsp;</b><%= @info.real_region_name %>

Excellent, now if you fire up your rails development server and and navigate to http://localhost:3000 you will see a form requesting your ip address or hostname. Entering any ip address or host name will show the country, city, and region that ip is from. That's it! That's all there is to it! Thanks for reading!