我将如何自动检测用户的位置并保存在数据库中?

How would I automatically detect a user's location and save in db?

我目前有一个 Tracker 应用程序,我想让 Rails 通过 IP 地址检测用户的位置(在我的应用程序中注册)

并像 iplocation site.

一样保存 Latitude,Longitude

用户模型包含idusernameemailpasswordLatitudeLatitude

脚本形式 anujay - jsfiddle (http://jsfiddle.net/anujay0402/TPhUC/)

HTML

<h3>Client side IP geolocation using</h3>
<hr/>
<div id="ip"></div>
<div id="address"></div>
<hr/>Full response: <pre id="details"></pre>

脚本

$.get("http://ipinfo.io", function (response) {
    $("#ip").html("IP: " + response.ip);
    $("#address").html("Location: " + response.city + ", " + response.region + "," + response.country );
    $("#details").html(JSON.stringify(response, null, 4));
}, "jsonp");

输出

Client side IP geolocation using
IP: 45.11.14.1
Location: Chennai, Tamil Nadu,IN
Full response:
{
    "ip": "45.11.14.1",
    "hostname": "45.11.14.1.live.vodafone.in",
    "city": "Chennai",
    "region": "Tamil Nadu",
    "country": "IN",
    "loc": "13.03,80.23",
    "postal": "009144",
    "org": "AS38266 Vodafone Essar Ltd., Telecommunication - Value Added Services,"
}

如果您不想弄乱会话信息,Devise gem 实际上允许您捕获 IP 地址。

查看 Devise 的可跟踪功能 here

您可以将用户的 ip 地址传递到 API 中,将 ip 映射到一个位置。

实现此目的的一种方法是在 lib 中创建一个 ruby 模块,该模块具有接收 IP 地址并向 API 发送请求以获取位置的方法。

module Location
  require 'net/http'
  require 'json'

  def get_location ip_address
    location = Net::HTTP.get(URI("https://ipapi.co/#{ip_address}/json/"))
    JSON.parse(location)
  end

  module_function :get_location
end

返回的JSON包括经度和纬度。

然后你可以从你的用户控制器调用这个方法

require 'location'

class UsersController < ApplicationController
  def create
    @user = User.new(params.require(:user).permit(:longitude, :latitude))
    location = get_user_location

    @user.longitude = location["longitude"]
    @user.latitude = location["latitude"]

    if @user.save
      # Do something
    else
      # Do somehting else
    end
  end

  private

  def get_user_location
    ip_address = request.remote_ip
    Location.get_location ip_address
  end
end 

注意:ip_address 不会在本地工作,因此要对其进行测试,您必须在 ip 地址中进行硬编码,而不是调用 request.remote_ip(即 ip_address =“8.8.8.8”)。

编辑: 更新用户位置需要的逻辑与在创建操作期间设置它的逻辑基本相同。所以,我建议将所有逻辑提取到模块中......像这样

module Location
  require 'net/http'
  require 'json'

  def get_location ip_address
    location = Net::HTTP.get(URI("https://ipapi.co/#{ip_address}/json/"))
    JSON.parse(location)
  end

  def set_location user ip_address
    location = get_location ip_address
    user.longitude = location["longitude"]
    user.latitude = location["latitude"]
    user.save
  end

  module_function :set_location
end

这将使您摆脱用户控制器中的所有位置逻辑,然后在整个控制器中重用 set_location 方法。