如何使用相关模型上的地理编码器按距离对记录数组进行排序?

时间:2014-11-20 21:01:24

标签: ruby-on-rails rails-geocoder

我在Rails 4上使用地理编码器来处理位置。

我有两个模型列表和位置

清单

class Listing < ActiveRecord::Base
  has_many :locations
end

位置

class Location < ActiveRecord::Base
  belongs_to :listing
  geocoded_by :full_address
  after_validation :geocode

  def full_address
    [street, city, state, country].compact.join(", ")
  end
end

我尝试创建一个简单的搜索功能,用户在城市中键入并返回搜索查询50英里范围内的列表列表。

我的搜索功能正在我的列表控制器索引操作中处理

def index
    @query = Geocoder.search(params[:q]).first
    @location = Location.near(@query.address, 50).order("distance")
    @listings = Listing.find(@location.map(&:listing_id))
end

我希望返回的结果按距离搜索的城市排序。当我搜索时,返回的结果由列表ID排序。

我能够做到这一点的唯一方法就是像我这样做@listings变量

def index
    @query = Geocoder.search(params[:q]).first
    @location = Location.near(@query.address, 50).order("distance")
    @listings = []
    @location.each do |l|
      @listings.push(Listing.find(l))
    end
end

但这会运行一堆数据库查询,我担心有很多记录和搜索,数据库会有很多压力。

是否有更简洁的方式让阵列以我想要的方式排序?谢谢。

2 个答案:

答案 0 :(得分:0)

ActiveRecord.find接受一个数组,在这种情况下会执行单个查询。因此,如果您可以为单个位置执行Listing.find,那么就可以轻松地为整个阵列执行此操作:

def index
  @query = Geocoder.search(params[:q]).first
  @location = Location.near(@query.address, 50).order("distance")
  @listings = Listing.find(@location)
end

然后应该执行三个查询:Geocoder搜索,Location查询,然后是单个Listing查询。

(此时我不再需要进行优化了。)

答案 1 :(得分:0)

所以我找到了一种更好的方法来对List数组进行排序。

        @listings = Listing.find(@location.map(&:listing_id)).sort_by{|listing| listing.locations.first.distance_to(@query.address)}

我可能会在未来遇到问题,因为我在将来添加了每个列表中有多个位置的功能,但是现在这种情况有效,我会来到这个桥上,