在rails视图中显示虚拟字段

时间:2014-12-30 23:12:36

标签: ruby-on-rails-4 postgis postgresql-9.2 ruby-on-rails-4.1

我一直在使用此处的信息(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查询的复杂性是什么?

我错过了ProjectTask模型中的某些内容,以允许虚拟/计算距离字段显示?

由于

1 个答案:

答案 0 :(得分:0)

复杂的结构被数据库视图取代。

有关如何执行此操作的更多详细信息,请参阅本教程(http://pivotallabs.com/database-views-performance-rails/)以及此处的其他SO问题(Connecting database view with polymorphic model in rails)。