【问题标题】:How to sort a custom column in ActiveAdmin?如何在 ActiveAdmin 中对自定义列进行排序?
【发布时间】:2019-06-07 11:14:30
【问题描述】:

我正在尝试对 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

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

【问题讨论】:

  • 欢迎 Srdjan :) 正在注册的资源的名称是什么?我在猜测 Route,但不确定您是否也将 |cd| 用于 driver 列?

标签: ruby-on-rails activeadmin


【解决方案1】:

我认为您需要先重构您的方法,使其成为 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

【讨论】:

    【解决方案2】:

    参考Tomáš' answer基于视图的模型解决方案的链接似乎已更改为:https://danchak99.wordpress.com/enterprise-rails/chapter-11-view-backed-models/

    我知道不鼓励发布答案以回复另一个答案,但我没有因果报应让 cmets 留下答案。我想与需要此信息的其他人分享此说明。

    【讨论】:

    • 嘿,谢谢,我用新链接更新了现有答案。但是会建议在这里删除此答案,希望您能理解。
    【解决方案3】:

    简而言之,您尝试使用的方式无法按虚拟属性排序。

    这就是原因。当您请求按属性对索引页进行排序时,会创建数据库查询,要求 DB 按该列对记录进行排序。在该查询中,将应用过滤器(如果提供),并且您的 drivers 表中的结果记录按选定的实际属性排序,并且仅返回一个子集(取决于您在 config/initializers/active_admin.rbconfig.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://danchak99.wordpress.com/enterprise-rails/chapter-11-view-backed-models/

    【讨论】:

      猜你喜欢
      • 2022-11-29
      • 2019-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-11
      相关资源
      最近更新 更多