Rails,如何对集合进行排序,最后保留特定值

时间:2021-08-01 14:28:30

标签: ruby-on-rails activerecord

我有一些对象的活动记录集合...

#<CoverElement:0x00007f87a4d78718
  id: 312,
  title: "Title 1",
  link: "",
  coverable_id: 35001,
  coverable_type: "Article",
  created_at: Thu, 07 May 2020 16:55:00 CEST +02:00,
  updated_at: Thu, 07 May 2020 16:55:00 CEST +02:00,
  cover_id: 4,
  format: "small",
  custom_image: nil,
  position: 2,
  second_title: nil,
  second_title_url: nil>,
 #<CoverElement:0x00007f87a4d6fde8
  id: 313,
  title: "Title 2",
  link: "",
  coverable_id: 35010,
  coverable_type: "Article",
  created_at: Thu, 07 May 2020 16:55:00 CEST +02:00,
  updated_at: Sun, 22 Nov 2020 19:33:39 CET +01:00,
  cover_id: 4,
  format: "horizontal",
  custom_image: nil,
  position: 3,
  second_title: nil,
  second_title_url: nil>

对于网站的桌面版,我使用仓位作为订单,但移动版我需要另一个订单。 我需要按格式排序,“小”必须排在最后。

基本上格式可以是:“大”、“垂直”、“水平”和“小”。

我试试

@elements.reorder('format ASC')

它可以工作,但当然它会保持“水平”、“大”、“垂直”和“小”的顺序

格式为“小”的每个对象都必须在末尾。有没有办法做到这一点,或者我必须编写自定义排序方法?

1 个答案:

答案 0 :(得分:0)

移动版本需要另一种排序方法。但是,如果您按格式排序,它将执行字母数字排序,这不会给您想要的结果(“小”在最后)。

有几种方法可以获得您想要的订单:

第一种方法是将格式列重新转换为枚举,以便数据库包含整数值 iso 字符串:

class CoverElement < ActiveRecord::Base
  enum format: [ :large, :vertical, :horizontal, :small ]
end

如果这是不可能的,你可以用这样的 sql 片段来做:

order = <<-ORD.squish
  CASE
    WHEN 'format'='large' THEN 4
    WHEN 'format'='vertical' THEN 3
    WHEN 'format'='horizontal' THEN 2
    WHEN 'format'='small' THEN 1
  END
ORD

CoverElement.order(order)