ruby-on-rails Rails:使用两个日期之一按范围对集合进行排序

ldioqlga  于 2022-11-26  发布在  Ruby
关注(0)|答案(2)|浏览(121)

我试图编写一个对两列中的一列进行排序的作用域--如果第一列(scheduled_at)中有数据,则使用该数据,否则使用created_at

def self.by_scheduled_at
  if scheduled_at
    order(scheduled_at: :desc)
  else
    order(created_at: :desc) 
  end  
end

此代码失败,因为scheduled_at是一个示例属性,而这是一个类方法。
如何编写此作用域,使其根据scheduled_at是否存在对集合进行排序?

doinxwow

doinxwow1#

我将假设你的意思是按created_at或sorted_at是否存在于每一行中来排序,也就是说,如果sorted_at有值,就使用它,但如果它是nil,就使用created_at。
| 已排序_at|创建时间|
| - -|- -|
| 2020年1月1日|2030年1月1日|
| 零值|2020年2月2日|
| 2020年3月3日|零值|
| 2020年4月4日|1999年1月1日|
为此,可以使用coalesce;它返回第一个非空值。然后将其写为作用域。

scope :by_scheduled_at, -> { order("coalesce(scheduled_at, created_at) DESC") }
oogrdqng

oogrdqng2#

如果你想要一个可链接的作用域,应该可以这样做(通过mysql2 gem在MySQL上测试):

scope :by_scheduled_at, -> { order(Arel.sql("IFNULL(scheduled_at, created_at) DESC")) }

正如@Schwern所指出的,IFNULL是MySQL特有的,使用COALESCE表示标准SQL(也由SQLite和PostgreSQL实现)。

相关问题