我正在使用此代码在我的网站上获取指定距离内的所有广告。我有两个模型,广告和位置。每个广告都有_位置。我正在对每个位置的地址字段进行地理编码,以找到在用户搜索范围内的地址字段。
这段代码可能需要重构,但我设法让它做我需要的东西;当用户搜索地址时,会显示特定距离内的所有广告。
问题在于代码会对每个广告执行查询,并且在我的数据库中有1000个广告,这很快就超出了谷歌地图的限制。我有按钮,用户可以点击这些按钮来更改搜索距离,每次点击都会再次对每个广告执行查询。有没有其他方法可以编写这个不需要这么多查询的方法?
#find ads with locations in range of user address search
ads_within_distance = Ad.select { |ad| ad.location.distance_from(cookies[:search_address]) <= distance.to_f }
ads_within_distance.each do |ad|
nearby_ads_id_array = ad.id
end
@nearby_ads = Ads.where(id: nearby_ads_id_array).paginate(:page => params[:page], :per_page => 5).order('created_at DESC')
显然可以这样做,因为很多网站如meetup.com都有此功能。我愿意使用最有效的方法。我真的很感激任何意见。
答案 0 :(得分:2)
您的方法存在两个问题。我假设一个位置可以有很多广告。如果是这种情况,您的关联应该是:
class Location < ActiveRecord::Base
has_many :ads
...
end
class Ad < ActiveRecord::Base
belongs_to :location
...
end
由于您正在迭代广告,因此您可能会多次检查相同位置的距离。
其次,由于您传递了一个地址,因此即使您只有一个您没有lat和long(用户输入的地址)的地址,您也会对每个广告进行地理编码。我假设您在数据库中的位置已经过地理编码,并且每个都有一个lat和long。
如果您使用地理编码器gem(https://github.com/alexreisner/geocoder),您可以写:
nearby_locations = Location.near(cookies[:search_address], distance.to_f)
然后,您可以通过以下方式找到属于这些位置的所有广告:
nearby_ads = Ad.where(location_id: nearby_locations)
祝你好运。