【发布时间】:2014-12-30 23:12:35
【问题描述】:
我一直在使用此处的信息 (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 选择中的列之一,与 tasks.* 一起,距离被正确用于对结果进行排序,但我不确定如何在我的视图中显示距离。
如果我做<%= result.distance.to_s %>,它说距离是一个未定义的方法。我对<%= result.project.distance.to_s %> 也不满意。而 <%= result.task_field %> 和 <%= result.project.project_field %> 工作正常。
我在 RoR 世界中没有看到太多同时使用 .joins() 和 .includes(),但它确实让我减少了 db 调用的数量,同时仍然产生了正确的 sql select 语句。 .无论如何,在我的情况下 - 这就是它们都被使用的原因。
我错过了什么吗?
是因为我的 AR 查询的复杂性造成的吗?
我是否在我的 Project 或 Task 模型中遗漏了一些东西以允许显示虚拟/计算距离场?
谢谢
【问题讨论】:
标签: ruby-on-rails-4 postgis postgresql-9.2 ruby-on-rails-4.1