Getting a user country name from originating IP address with Ruby on Rails
You can also use "Geocoder"
It will just make you life easier. Put the following line in your Gemfile and issue the bundle install command
gem 'geocoder'
Using this Gem, you can easily get the country, ip or even city of the originating IP. See an example below
request.ip # => "182.185.141.75"
request.location.city # => ""
request.location.country # => "Pakistan"
I'm using this one-liner:
locale = Timeout::timeout(5) { Net::HTTP.get_response(URI.parse('http://api.hostip.info/country.php?ip=' + request.remote_ip )).body } rescue "US"
You can use geoip
gem.
environment.rb
config.gem 'geoip'
Download GeoIP.dat.gz
from http://www.maxmind.com/app/geolitecountry
. unzip the file. The below assumes under #{RAILS_ROOT}/db
dir.
@geoip ||= GeoIP.new("#{RAILS_ROOT}/db/GeoIP.dat")
remote_ip = request.remote_ip
if remote_ip != "127.0.0.1" #todo: check for other local addresses or set default value
location_location = @geoip.country(remote_ip)
if location_location != nil
@model.country = location_location[2]
end
end
The simplest is to use an existing web service for this.
There are plugins that let you do much more, including making your models geolocation-aware (geokit-rails) automatically, but if all you need is a country code for example, simply sending an HTTP Get to http://api.hostip.info/country.php
(there are other services but this one does not require an API key) will return it, e.g. :
Net::HTTP.get_response(URI.parse('http://api.hostip.info/country.php'))
=> US
Or polling http://api.hostip.info/ will return a full XML response with city, latitude, longitude, etc.
Be aware that the results you get are not 100% accurate. For example, right now I'm in France but reported as in Germany. This will be the case for pretty much any IP-based service.