【问题标题】:Ruby geocoder: Geocoding a second set of coordinates on the same modelRuby 地理编码器:在同一模型上对第二组坐标进行地理编码
【发布时间】:2021-08-21 01:37:06
【问题描述】:

我们想让我们网站的成员列出第二个家,供那些在一个地方过冬而在另一个地方过夏天的人。 geocoder's documentation 解释了如何对第二组坐标执行查询,但没有说明如何在数据库中设置第二对坐标以便我们可以对其进行搜索。

如果我们这样做,例如:

geocoded_by :location, latitude: :latitude, longitude: :longitude
after_validation :geocode, if: ->(obj) { obj.location.present? && obj.location_changed? }
reverse_geocoded_by :latitude, :longitude, location: :location do |obj, results|
  if (geo = results.first)
    obj.city         = geo.city
    obj.state        = geo.state
    obj.country      = geo.country
    obj.state_code   = geo.state_code
    obj.country_code = geo.country_code
  end
end
after_validation :reverse_geocode, if: ->(obj) { obj.location.present? && obj.location_changed? }

geocoded_by :location2, latitude: :latitude2, longitude2: :longitude2
after_validation :geocode, if: ->(obj) { obj.location2.present? && obj.location2_changed? }
reverse_geocoded_by :latitude2, :longitude2, location: :location2 do |obj, results|
  if (geo = results.first)
    obj.city2         = geo.city
    obj.state2        = geo.state
    obj.country2      = geo.country
    obj.state_code2   = geo.state_code
    obj.country_code2 = geo.country_code
  end
end
after_validation :reverse_geocode, if: ->(obj) { obj.location2.present? && obj.location2_changed? }

似乎第二个geocoded_by 覆盖了第一个而不是添加第二个操作。谁能建议一种方法来做到这一点?

非常感谢!

【问题讨论】:

  • 更好的架构是说user has_many :locations(或限制为两个),然后对位置本身进行地理编码。或者,您可以将位置作为模型(地理编码)和用户has_one :primary_location, class_name: "Location"secondar_location,其中您有primary_location_id
  • 感谢您的想法,@TimKretschmer!但是一旦我将地理编码数据移动到一个单独的模型中,我该如何做相当于User.near('Omaha, NE, US')(包括主要和次要位置)?我知道如何查询位置,但如何查询这些位置附近的用户?
  • 这很容易,并且可以通过一个连接或 2 个单独的查询来实现。基本上你想要Location.near("Omaga, NE, US"),然后是pluck(:user_id)。然后User.where(id: near_ids)。或者,您可以通过 join 一次性解决。但这是要走的路。
  • 谢谢,@TimKretschmer!我没有忘记你。我开始使用你的想法,然后意识到我们可以对我们网站的其他部分使用地址(地点、组、事件等)做同样的事情,所以我扩展了计划以合并多态关联,并且我深陷其中的困难. ???我会在它工作时报告。
  • 这听起来很正确。基本上是所有位置的模型,它被地理编码,所有其他模型都可以引用这些位置之一。就这么简单。

标签: ruby-on-rails ruby geocoding


【解决方案1】:

再次感谢您的帮助,@TimKretschmer;它对我们很有效。对于走这条路的人有几点注意事项:

首先,如果您创建多态关联,则 Locations 将与使用它们的模型以及这些模型的特定实例相关联。这意味着,充其量,您可以为每个 User + user_id、每个 Event + event_id 等创建(和索引)一个位置。这有点令人失望——我宁愿为“Paris”创建一个位置" 一切都使用了。我什至看起来都不能为所有用户提供一个位置;用户 3 将有一个“巴黎”位置,用户 437 将有另一个“巴黎”位置。

仍然有效。我通过 Geocoder 运行用户的输入并在我们遇到问题时保存结果,从而对其进行了一些清理:

def create
    location = Geocoder.address(params[:user][:location])
    params[:user][:location] = location unless location.nil?
    location2 = Geocoder.address(params[:user][:location2])
    params[:user][:location2] = location2 unless location2.nil?
    @user = User.new(user_params)

   [etc.]

 end

最重要的是,任何这样做的人都需要知道the way Geocoder uses ActiveRecord 意味着您不能将plucknear 一起使用。我最终改用map

User.where(id: [Location
        .where(locatable_type: 'User')
        .near(@search_place, @search_distance)
        .map(&:locatable_id)])

最好的祝愿,
杰夫

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-05
    相关资源
    最近更新 更多