如何在ActiveAdmin中对自定义列进行排序?

时间:2019-06-07 11:14:30

标签: ruby-on-rails activeadmin

我正在尝试在ActiveAdmin的索引页上对自定义列进行排序,以显示由助手方法提供的数据。

我尝试了多种排序解决方案,但没有一个起作用。我当时正在考虑尝试对自定义范围进行排序,但是我正在Active Admin中寻找解决方案。

 index do
    selectable_column
    id_column
    column ("Driver") { |cd| link_to("#{cd.campaign_driver.full_name}", admin_driver_path(cd.campaign_driver.driver_id)) }
    column :started_at
    column :ended_at
    column ("Distance(km)") { |route| route_distance(route) }
    column ("Clean distance(km)") { |route| route_clean_distance(route) }
    column ("Distance diff(km)") { |route| route_distance_diff(route) }
    column ("Duration") { |route| route_duration(route) }
    column ("Average speed") { |route| route_avg_speed(route) }
    actions
  end

“距离差异”列应可排序。

2 个答案:

答案 0 :(得分:0)

简而言之,无法通过您尝试使用的方式对虚拟属性进行排序。

这就是原因。当您请求按属性对索引页进行排序时,将创建数据库查询,要求DB按该列对记录进行排序。在该查询中,将应用过滤器(如果提供),并且drivers表中的结果记录将按选定的真实属性和仅一个子集(取决于config/initializers/active_admin.rb config.default_per_page = 30中的分页设置进行排序)返回。您的辅助方法将应用于此子集(因此,如果它起作用,它将仅在其中排序约30条记录)。数据库不知道您的虚拟属性,因此无法对所有记录进行相应的排序。

对此至少有两种解决方案:

1)默认范围

简单的解决方案是使用Rails自己的default_scope。它修改了用作模型查询构建器基础的基础查询。您可以在那里卸载虚拟字段的构造,然后在Rails中使用它,请参见下面的示例。 有缺点:1)如果您的虚拟字段依赖于其他表,将会变得很困难,2)通常建议不要使用默认范围-谷歌“ rails default scope bad”要赶上。

class Route < ApplicationRecord
  default_scope { select(Arel.star, 'md5(name) hashed_name') }
  ...
end

ActiveAdmin.register Route do
  index do
    column :hashed_name, sortable: true
  end
end

2)基于视图的模型

适当但又更复杂的解决方案是创建一个数据库视图,该视图将计算所需的所有虚拟字段,然后基于该视图构建Rails模型。这是可以帮助您实现这一目标的资源-https://dan.chak.org/enterprise-rails/chapter-11-view-backed-models/

答案 1 :(得分:0)

我认为您需要首先重构您的方法,使其成为scoped_collection。

controller do
  def scoped_collection
    Route.select("routes.*, (routes.ended_at-routes.ended_at) AS distance_diff_route")
  end
end

然后将索引列重写为

column :distance_diff_route, sortable: :distance_diff_route