Active Record 结果以特定方式排序

Active Record results to be ordered in specific way

我有作业 table,列为 job_typejob_type 可以是 tophotnormal。现在,当我列出所有职位时,我希望首先显示 top 个职位,然后是 hot 个职位,最后是 normal 个职位。我还想按降序对作业进行排序(created_at: :desc)。我有以下范围

class Job < ApplicationRecord
  scope :hot_jobs, -> { where(job_type: 'hot') }
  scope :top_jobs, -> { where(job_type: 'top') }
  scope :normal_jobs, -> { where(job_type: 'normal') }
end

我试过了

在控制器中我试过这样的东西

@jobs = Job.hot_jobs.order(created_at: :desc).or(Job.top_jobs.order(created_at: :desc)).or(Job.normal_jobs.order(created_at: :desc))

但是上面的代码不起作用。以上代码结果与 Job.all.order(created_at: :desc)

相同

那么我怎样才能按照 Top Jobs 然后 Hot Jobs 然后 Normal Jobs 的顺序列出工作。如果我使用数组,我可以做一些修改,但我不想将 ActiveRecord#Relations 转换为数组,因为这会导致 will_paginate 出现问题,而且我不能使用 includes 来防止 N + 1查询

我正在使用 Rails 6.0.4.1

更新

我将 job_type 列更改为 integer 但我做不到

@jobs = Job.active.order(job_type: :asc, created_at: :desc).limit(48)

问题已解决。

只需在订单中使用 case 语句即可。

Rails 6 中的诀窍是将它包装在 Arel.sql 中,否则你会得到一个“non-attribute 参数”错误

@jobs = Job.all.order(
        Arel.sql(
          "case when job_type = 'top' then 1 
           when job_type = 'hot' then 2
           else 3 end asc"), created_at: :desc)

如果您在工作中有默认订单范围,只需将 order 更改为 reorder