ActiveRecord条件顺序子句

时间:2015-02-13 20:34:22

标签: activerecord conditional

我需要对任务列表进行排序:

|----------------------------------------------------------------------|
| title                            | priority    | due_at              |
| ---------------------------------|-------------|---------------------|
|  Mow the lawn                    |           1 | 2011-09-11 22:00:00 |
|  Call mom                        |           3 | 2010-01-26 09:29:03 |
|  Bake a cake                     |           2 | 2013-09-13 08:45:37 |
|  Feed the cat                    |           2 | 2015-09-12 16:03:51 |
|  Remember you don't like the cat |           2 | 2014-03-19 23:00:00 |
|----------------------------------------------------------------------|

订单子句应按优先级对所有过期任务进行排序,所有其他任务按due_at排序,例如:结果顺序应为

  • 割草坪
  • 烤蛋糕
  • 致电妈妈
  • 记住你不喜欢猫
  • 喂猫

2 个答案:

答案 0 :(得分:1)

我最终得到了以下内容(纯SQL,尚未翻译成AR):

SELECT *
FROM tasks 
ORDER BY 
    due_at <= Now() DESC,
    CASE due_at <= Now()  WHEN true THEN priority END ASC,
    CASE due_at <= Now()  WHEN true THEN due_at END ASC,
    CASE due_at <= Now()  WHEN false THEN due_at END DESC,
    CASE due_at <= Now()  WHEN false THEN priority END ASC

答案 1 :(得分:0)

如果你只需要存储在@tasks中的一系列任务,你可以这样做:

@tasks = Task.where(due_at: 10.years.ago..Time.now).order(:priority)
@tasks += Task.where.not(due_at: 10.years.ago..Time.now).order(:due_at)

如果您需要Task::ActiveRecord_Relation,则必须执行此操作:

Task.where(id: Task.where(due_at: 10.years.ago..Time.now).
               order(:priority).pluck(:id) + 
               Task.where.not(due_at: 10.years.ago..Time.now).
               order(:due_at).pluck(:id))