【问题标题】:Geokit and Authlogic, geocoding the users ip address when they create a userGeokit 和 Authlogic,在创建用户时对用户 IP 地址进行地理编码
【发布时间】:2009-08-22 19:08:21
【问题描述】:

有人做过吗?我对如何使这项工作感到困惑,首先我有我的用户模型

使用它进行地理编码在 IRB 中工作正常,只是无法弄清楚如何让它在我的项目中工作。

尝试在此处使用自述文件中的一些示例:http://github.com/andre/geokit-rails/tree/master

这就是我所拥有的:

class User < ActiveRecord::Base

  # geokit
  acts_as_mappable

  after_save :locate

  def locate
    location = Geokit::Geocoders::MultiGeocoder.geocode("12.12.12.12")
  end

end

这与我在userController 中的保存操作相对应,我需要在保存后执行此操作,因为 authlogic 在保存用户或会话后提供 IP。我想最终我会把它变成一个后台进程,但在那之前我怎样才能让它工作呢?我在用户模型中有一个位置列,我将存储geocode() 的结果

另外,我现在只有一些任意 IP 地址“12.12.12.12”,但它实际上应该是 current_login_ip

【问题讨论】:

    标签: ruby-on-rails activerecord model geokit


    【解决方案1】:

    对于我目前的一个项目,我完成了与您正在尝试做的非常相似的事情。要考虑的一件大事是,您不希望每次保存模型时都执行新的地理编码请求。如果您不需要每次都获取新的地理坐标,则这样做相当耗时且效率低下。

    此外,从 IP 地址获得的地理编码结果非常不准确。有时你会得到不错的结果,但很多时候你会得到附近另一个城镇的某个数据中心的坐标。如果您正在寻找区域精度,IP 地理编码精度可能足以满足您的要求。

    如果属性没有改变,我就是这样解决不重新请求地理编码的问题:

    require 'us_states' # this is just an array of states and abbreviations
    include Geokit::Geocoders
    
    class Location < ActiveRecord::Base
    
        acts_as_mappable
    
        validates_presence_of :name, :address_1, :city, :state, :zip
        validates_format_of :zip, :with => /^([0-9]{5})(-[0-9]{4})?$/
        validates_inclusion_of :state, :in => US_STATES_ABRS
    
        before_save :get_geo_coords
    
        # request_geocoding attribute is intended to help with unit testing
        attr_accessor_with_default :request_geocoding, true
    
        private
    
        def get_geo_coords
            # if lat and lng are already defined
            if self.lat && self.lng && self.id
                # find existing location
                l = Location.find(self.id)
                # and if location params are the same as existing location
                # then we do not need to request geocords again
                loc_attrs = %w{address_1 address_2 city state zip}
                if loc_attrs.all? {|attr| self.attribute_for_inspect(attr) == l.attribute_for_inspect(attr)}
                    self.request_geocoding = false
                end
            end
            if self.request_geocoding
                # Request new geocoding
                loc = MultiGeocoder.geocode("#{self.address_1}, #{self.city}, #{self.state}, #{self.zip}")
                if loc.success
                    self.lat = loc.lat
                    self.lng = loc.lng
                else
                    errors.add_to_base("Unable to geocode your location.  Are you sure your address information is correct?")
                end
            end
        end
    end
    

    【讨论】:

    • 太棒了!我现在正试图让它工作,但这很有帮助,特别是 if loc.success 块有很大帮助。
    【解决方案2】:

    我自己没有使用过 geokit,所以无法发表评论。但是我想我应该提到支持 HTML 5 的浏览器(例如 Firefox 3.5)支持地理定位 API,以防您不知道。

    【讨论】:

    • 这是一个很好的提示,我正在考虑在某个时候使用客户端,并在浏览器找到用户后使用 ajax 进行 POST。但直到那天,我仍然需要使用服务器对 IP 地址进行地理编码。唉……浏览器接受速度慢(呃……IE不接受)
    • 比较这两种不同的方法会很有趣,看看对于 Firefox、Safari、Chrome,这两种方法之间有多大程度的差异......
    【解决方案3】:

    看看这个网站:

    http://geokit.rubyforge.org/readme.html

    向下滚动到 IP Geocoding 和 IP Geocoding Helper 部分。

    “您可以随时使用地理编码器获取 IP 的位置,如下例所示:”

    location = IpGeocoder.geocode('12.215.42.19')
    

    “其中 Location 是一个 GeoLoc 实例,包含纬度、经度、城市、州和国家代码。此外,成功值为 true。”

    获得 GeoLoc 后,只需拉取用户模型,设置其长/纬度列并保存即可。

    GeoLoc 文档:http://geokit.rubyforge.org/api/geokit-gem/Geokit/GeoLoc.html

    我错过了什么吗?

    【讨论】:

    • 好吧,你明白了,问题是我的 GeoKit 运行良好,我只是很难弄清楚如何在用户登录后将其正确保存到我的用户模型中.
    猜你喜欢
    • 1970-01-01
    • 2011-03-15
    • 2014-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    相关资源
    最近更新 更多