我一直在使用此处的信息(http://ngauthier.com/2013/08/postgis-and-rails-a-simple-approach.html),以便可以根据邻近度显示我的应用中的搜索结果。
我列出所有任务及其相关的项目信息 - 项目可以有多个任务。
我的Project
控制器中有以下AR查询:
@results = Task.select('tasks.*') # .select('tasks.*') required for pg_search
.joins(:project => :user)
.includes(:project => :user)
.merge(Project.enabled_only.filter_by_location(@geo).search(params[:q]))
.order_results(sort)
在Project
模型中,我有:
scope :distance_from, ->(latitude, longitude) {
select(%{
ST_Distance(
ST_GeographyFromText(
'SRID=4326;POINT(' || projects.longitude || ' ' || projects.latitude || ')'
),
ST_GeographyFromText('SRID=4326;POINT(%f %f)')
) AS distance
} % [longitude, latitude])
}
scope :near, ->(latitude, longitude, distance_in_meters = 1000) {
where(%{
ST_DWithin(
ST_GeographyFromText(
'SRID=4326;POINT(' || projects.longitude || ' ' || projects.latitude || ')'
),
ST_GeographyFromText('SRID=4326;POINT(%f %f)'),
%d
)
} % [longitude, latitude, distance_in_meters])
}
def self.filter_by_location(geo_location)
scoped = self.all
if geo_location.present?
scoped = scoped.distance_from(geo_location[:lat], geo_location[:lng])
scoped = scoped.near(geo_location[:lat], geo_location[:lng])
end
scoped
end
然后我的Task
模型中有以下内容:
scope :distance_order, -> { order('distance') }
def self.order_results(sort)
# order scopes are appended
scoped = self.all.reorder('')
# check sql for search and distance fields
search_performed = scoped.to_sql.downcase.include?(' pg_search_rank')
distance_calculated = scoped.to_sql.downcase.include?(' distance')
if sort == 'rel'
# rel,dist
scoped = scoped.search_rank_order if search_performed
scoped = scoped.distance_order if distance_calculated
else
# dist,rel
scoped = scoped.distance_order if distance_calculated
scoped = scoped.search_rank_order if search_performed
end
scoped = scoped.name_order
scoped
end
这适用于我的应用,可以通过邻近度对结果进行排序。
距离是AR查询生成的sql select中的一列,以及tasks.*
,正确使用距离对结果进行排序,但我不确定如何在视图中显示距离。
如果我<%= result.distance.to_s %>
,则表示距离是未定义的方法。我对<%= result.project.distance.to_s %>
也没有任何喜悦。而<%= result.task_field %>
和<%= result.project.project_field %>
工作正常。
我没有在RoR世界中同时看到过多使用.joins()
和.includes()
但它确实允许我减少db调用的数量,同时仍然生成正确的sql无论如何,在我的情况下选择陈述......这就是为什么它们都被使用了。
我错过了什么吗?
导致它的AR查询的复杂性是什么?
我错过了Project
或Task
模型中的某些内容,以允许虚拟/计算距离字段显示?
由于
答案 0 :(得分:0)
复杂的结构被数据库视图取代。
有关如何执行此操作的更多详细信息,请参阅本教程(http://pivotallabs.com/database-views-performance-rails/)以及此处的其他SO问题(Connecting database view with polymorphic model in rails)。