3

I want to replace the 127.0.0.1 IP that I have in the development environment in order to test manually the geocoder gem. How can I do that ?

I tried that, but it doesn't work. I meet the following error :

.rvm/gems/ruby-2.0.0-p247/gems/activesupport-4.0.0.rc1/lib/active_support/infle‌​ctor/methods.rb:226:in 'const_get': uninitialized constant SpoofIp (NameError)
Community
  • 1
  • 1
Flo Rahl
  • 1,044
  • 1
  • 16
  • 33

4 Answers4

5

My answer not for everyone since I wanted to test request.location locally only. But if you want to do the same then I have the solution for you. First of all, let me show you source code for .location method:

module Geocoder
  module Request

    def location
      @location ||= begin
        detected_ip = env['HTTP_X_REAL_IP'] || (
          env['HTTP_X_FORWARDED_FOR'] &&
          env['HTTP_X_FORWARDED_FOR'].split(",").first.strip
        )
        detected_ip = IpAddress.new(detected_ip.to_s)
        if detected_ip.valid? and !detected_ip.loopback?
          real_ip = detected_ip.to_s
        else
          real_ip = self.ip
        end
        Geocoder.search(real_ip).first
      end
      @location
    end
  end
end

# ...

As you can see, there is variable detected_ip and to find it's data gem checks out env['HTTP_X_REAL_IP']. Well, now we can easily stub that in our controller:

class HomeController < ApplicationController    
  def index
    env['HTTP_X_REAL_IP'] = '1.2.3.4' if Rails.env.development?
    location = request.location

    # => #<Geocoder::Result::Freegeoip:0x007fe695394da0 @data={"ip"=>"1.2.3.4", "country_code"=>"AU", "country_name"=>"Australia", "region_code"=>"", "region_name"=>"", "city"=>"", "zipcode"=>"", "latitude"=>-27, "longitude"=>133, "metro_code"=>"", "area_code"=>""}, @cache_hit=nil> 
  end
end

It works with geocoder '1.2.5' (can't promise that it works with earlier versions - you need check out source code for that or bump the gem).

ExiRe
  • 4,727
  • 7
  • 47
  • 92
  • 1
    So good, thanks a lot! I'd put that `env[HTTP_X_REAL_IP]` in a before_filter in `ApplicationController` of course use it only in development. – ellmo Oct 30 '14 at 21:09
  • 1
    Geocoder 1.2.6 [has changed](https://github.com/alexreisner/geocoder/blob/c1010e629a4676c1b300ea26805ab0a7991edf9b/lib/geocoder/request.rb#L62). Use `env['REMOTE_ADDR']` instead. – Brian Jun 02 '15 at 16:26
3

This is the correct answer:

class ActionDispatch::Request
  def remote_ip
    "1.2.3.4"
  end
end
BWStearns
  • 2,567
  • 2
  • 19
  • 33
1

Add this to your config/environments/development.rb.

class ActionController::Request
  def remote_ip
    "1.2.3.4"
  end
end

Restart your server.

HariKrishnan
  • 456
  • 3
  • 14
  • 1
    Thanks ! But why `ActionController` and not `ActionDispatch` ? – Flo Rahl Sep 17 '13 at 09:35
  • 1
    It doesn't work :-( If I do something like `

    Current Location :

    <%= request.location.city %>`, the page renders only `

    Current Location :

    `
    – Flo Rahl Sep 18 '13 at 06:30
0

This is an updated answer for geocoder 1.2.9 to provide a hardcoded IP for development and test environments:

if %w(development test).include? Rails.env
  module Geocoder
    module Request
      def geocoder_spoofable_ip_with_localhost_override
        ip_candidate = geocoder_spoofable_ip_without_localhost_override
        if ip_candidate == '127.0.0.1'
          '1.2.3.4'
        else
          ip_candidate
        end
      end
      alias_method_chain :geocoder_spoofable_ip, :localhost_override
    end
  end
end
kross
  • 3,627
  • 2
  • 32
  • 60