我有 3 个表:Objects
、Locations
、Hotels
。
每个对象有多个位置,每个位置有几个酒店(默认在 20 英里半径内)。
我的模型(略微简化以专注于主要内容)
对象.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 英里)内,对应于对象。
我想使用 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/