我有 3 个表: ObjectsLocationsHotels

每个对象有多个位置,每个位置有多个酒店(默认为 20 英里半径)。

我的模型(稍微简化它以专注于主要事情)

object.rb

attr_accessible :name

has_many :locations
has_many :hotels

location.rb
attr_accessible :name, :address, :longitude, :latitude

has_many :objects
has_many :hotels

hotels.rb
attr_accessible :name, :address, :longitude, :latitude

has_many :objects
has_many :locations

我想创建一个搜索表单,用户可以在其中输入对象的 名称 搜索半径

输出应该是所有酒店的列表,这些酒店位于距每个位置中心的给定半径(小于或等于 20 英里)内,对应于 object。

我想使用 Geocoder's gem 方法 near ,但我不确定如何构建此类任务的 Controller 层。

最佳答案

您希望数据库中有一个空间查询引擎来执行这些查询,例如MongoDB 或 PostGIS(在 Postgres 中)。我认为您正在寻找的答案会因您使用的答案而异。我将 PostGIS 用于这些东西并且非常喜欢它。

也就是说,Geocoder 可用于在没有空间查询引擎的情况下在内部为其提供动力,尽管它的效率不高。如果你真的变大了,它就会停下来。如果你看一下来源:https://github.com/alexreisner/geocoder/blob/master/lib/geocoder/stores/active_record.rb

# skeleton for the controller method
obj = Object.find(name)
locations = obj.locations
near_hotels = locations.map do |loc|
  locations.hotels.near([loc.latitude, loc.longitude])
end

不确定 Near 方法是否正确采用了 radius 参数,但是您可以通过基本上复制它来轻松编写自己的方法:
# on the hotel class
def nearby(lat, lon, radius)
    options = self.send(:near_scope_options, lat, lon, radius, {})
    select(options[:select]).where(options[:conditions]).
      order(options[:order])
}

我强烈建议您查看 PostGIS。

注意,我的示例方法产生了一个关系。您可以通过将范围限定到与您的目标相匹配的酒店来缩小您的选择范围。

关于database - 在给定半径内搜索相应对象位置的酒店(Gem Geocoder),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15324821/

10-11 05:24