4

I have a function in my controller that calls another function form the model that needs to be fed the ip address

  def get_location_users
    if current_user
      return current_user.location_users
    else

      l = Location.find_by_ip(request.remote_ip)

      lu = LocationUser.new({:location_id => l.id, :radius => Setting.get("default_radius").to_i})
      return [lu]
    end
  end

from what I gathered remote.request_ip gives you the ip address, however when I call that function with request.remote_ip the object is nil. If I put in a static ip address though it produces the right output. What would be the correct way to get the ip address if remote.request_ip does not do so?

also when I try typing "request.remote_ip" in the console it returns "undefined local variable or method "request" from main"

xxyyxx
  • 2,306
  • 3
  • 24
  • 34
  • Are you testing it in development or in production ? Also it is normal that it does not work on the rails console as the rails console does not respond to an http call so do not have a request object. – Adrien Coquio Nov 21 '12 at 17:03
  • Possible duplicate of [Rails: Get Client IP address](https://stackoverflow.com/questions/4465476/rails-get-client-ip-address) – Colby Cox May 23 '17 at 01:38

3 Answers3

6

Do you have a typo in your question or are you really calling remote.request_ip?

The correct method would be request.remote_ip

Tom Harrison
  • 13,533
  • 3
  • 49
  • 77
bob
  • 173
  • 1
  • 1
  • 7
3

This looks like code that should be in a model, so I'm assuming that's where this method is. If so, you can't (at least 'out of the box') access the request object from your model as it originates from an HTTP request -- this is also why you get "undefined local variable or method "request" from main" in your console.

If this method is not already in your model I would place it there, then call it from you controller and pass in request.remote_ip as an argument.

def get_location_users(the_ip)
  if current_user
    return current_user.location_users
  else
    l = Location.find_by_ip(the_ip)
    lu = LocationUser.new({:location_id => l.id, :radius => Setting.get("default_radius").to_i})
    return [lu]
  end
end

Then, in your controller ::

SomeModel.get_location_users(request.remote_ip)

Also, be aware that "Location.find_by_ip" will return nil if no records are matched.

And, you can issue a request in your console by using app.get "some-url", then you can access the request_ip from request object app.request.remote_ip and use it for testing if needed.

imgrgry
  • 628
  • 1
  • 5
  • 11
  • 1
    This is correct. The `request` object is available only in the context of a request, meaning: the controllers and views. It's not available in models (or mailers). So you have to get the ip and pass it to a model method, as in this example. – Tom Harrison Nov 21 '12 at 18:45
2
  • HTTP requests: request.ip (as sebastianh pointed out in his answer)

    also available as: request.env['action_dispatch.request_id']

  • HTTPS requests: request.env['HTTP_X_FORWARDED_FOR'].split(/,/).try(:first)

Ian Vaughan
  • 20,211
  • 13
  • 59
  • 79
Tilo
  • 33,354
  • 5
  • 79
  • 106