Ruby on rails 4 在rails视图中显示虚拟字段
我一直在使用这里的信息,以便在我的应用程序中的搜索结果可以显示的基础上接近 我列出了所有任务及其相关的项目信息-一个项目可以有多个任务 我的项目控制器中有以下AR查询:Ruby on rails 4 在rails视图中显示虚拟字段,ruby-on-rails-4,postgis,postgresql-9.2,ruby-on-rails-4.1,Ruby On Rails 4,Postgis,Postgresql 9.2,Ruby On Rails 4.1,我一直在使用这里的信息,以便在我的应用程序中的搜索结果可以显示的基础上接近 我列出了所有任务及其相关的项目信息-一个项目可以有多个任务 我的项目控制器中有以下AR查询: @results = Task.select('tasks.*') # .select('tasks.*') required for pg_search .joins(:project => :user) .includes(:project => :us
@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)
在我的项目模型中,我有:
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
然后,我的任务模型中包含以下内容:
对于我的应用程序来说,这可以很好地按邻近性对结果进行排序
距离是AR查询生成的sql select中的一列,以及tasks.*和Distance被正确用于对结果进行排序,但我不确定如何在视图中显示距离
如果我这样做,它说距离是一个未定义的方法。我对这两件事都不感兴趣。而且工作很好
在RoR世界中,我没有看到过太多同时使用.joins和.includes的情况,但它确实允许我减少了db调用的数量,同时仍然生成正确的sql select语句……无论如何,在我的例子中,这就是为什么它们都被使用的原因
我错过什么了吗
是我的AR查询的复杂性造成的吗
我的项目或任务模型中是否缺少允许显示虚拟/计算距离字段的内容
多亏了数据库视图取代了复杂的结构 关于如何做到这一点的更多细节可以在本教程和我的另一个SO问题中找到
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