【问题标题】:Unable to sort records in active admin by virtual attribute无法按虚拟属性对活动管理员中的记录进行排序
【发布时间】:2019-08-12 06:10:05
【问题描述】:

无法按虚拟属性对活动管理员中的记录进行排序。

我有一个模特Competition

竞赛有 2 列名为 starts_atends_at

比赛的starts_atends_at 日期可以是这些状态中的任何一种。

  • 打开如果starts_at < Time.now && ends_at > Time.now
  • 关闭如果Time.now > ends_at
  • 未打开如果starts_at > Time.now

我想按这个顺序对状态进行排序(也可以反过来)

  1. 打开在顶部
  2. 关闭打开后
  3. 最后没有打开

文件/admin/competition.rb

方法:index

虚拟属性:Status

column "Status" , sortable: true do |competition|
    competition.status
end

文件app/model/copetition.rb

获取状态的方法

def status
    return 'Unknown' unless (starts_at && ends_at)
    return 'Not Opened' if Time.now < starts_at
    return 'Open' if (Time.now > starts_at && Time.now < ends_at)
    return 'Closed' if Time.now > ends_at
end

我找不到应用这种排序的方法。

附加信息

'rails', '4.2.6'

ruby '2.2.4'

'activeadmin', '1.0.0.pre4'

【问题讨论】:

    标签: mysql ruby ruby-on-rails-4 activerecord activeadmin


    【解决方案1】:

    activeadmin 中无法按虚拟属性排序,因为排序是在 DB 级别执行的。

    但是,您可以使用相同的逻辑在 SQL 中计算所需的字段并使用它。

    您必须修改activeadmin 的默认集合 SQL 查询并添加您的计算字段才能使用它进行排序。

    # /admin/competition.rb
    
    ActiveAdmin.register Competition do
      # modify the collection SQL query to add the needed field
      controller do
        def scoped_collection
          super.select(
            "competitions.*,
             CASE
             WHEN starts_at < NOW() THEN 3
             WHEN ends_at > NOW() THEN 2
             ELSE 1
             END AS status_from_sql"
          )
        end
      end
    
      # using the added field for sorting
      column "Status" , sortable: "status_from_sql" do |competition|
        competition.status
      end    
    end
    

    【讨论】:

      【解决方案2】:

      将原始 SQL 与 ActiveRecord::QueryMethods#order 一起使用:

      .order("
        IF(starts_at < NOW() AND ends_at > NOW(), 1,
          IF (NOW() > ends_at, 0, -1)) DESC
      ")
      

      【讨论】:

      • 实际上我正在为此使用active_admin。使用默认排序功能。我不知道在哪里应用这段代码。我在比赛表中没有status 列。如何覆盖活动管理员的基本功能。
      • 我不确定我是否遵循。您是否在上面的 sn-p 中看到任何提及 status 的内容?这将对数据库中的记录进行排序,这是一种正确的方法。将其应用于从数据库中选择记录的位置。
      • 这是 active_admin 的默认排序。当我们在active admin 中的任何列上应用sortable 时,用户可以按这些列排序(ASCDESC)。以及对该特定列的活动管理查询。但我没有那个专栏。当我使用column "Status" , sortable: true 然后参数
      • 您必须手动处理此案。开发应用程序有时需要编写一些代码,而不仅仅是使用第三方库。
      • 这是我在active admin---index do selectable_column id_column column "Name", :title column "Organizer Name", :user_id column "Status" , sortable: true do |competition| competition.status end column :starts_at column :ends_at column :group_id column :submissions, sortable: 'competitions.submissions_count' do |competition| link_to competition.try(:submissions_count).to_i, admin_competition_submissions_path(competition) end actions end中的索引操作
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-20
      • 2015-11-07
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      相关资源
      最近更新 更多