如何按字符串排序,Ruby

问题描述 投票:0回答:2

所以我有@cake.type,它可以是“Primo”、“Multilayered”、“Decorative”、“On Sale”、“Basic”`

我想按顺序组织蛋糕列表。因此,所有“Primo”蛋糕都位于顶部,接下来是所有“多层”蛋糕,等等。每种类型的蛋糕都应按“created_at”进一步列出(最旧创建的蛋糕在前)。

@cakes = []
@cakes << @store.cakes.where(type: "Primo").order(created_at: :desc) 
@cakes << @store.cakes.where(type: "Multilayered").order(created_at: :desc) 
@cakes << @store.cakes.where(type: "Decorative").order(created_at: :desc) 
@cakes << @store.cakes.where(type: "On Sale").order(created_at: :desc) 
@cakes << @store.cakes.where(type: "Basic", "Basic").order(created_at: :desc) 

有没有一种方法可以通过一个查询来完成它?

...也许:

cake_eater_nom = []

c = @store.cakes
primo_cakes = c.where(type: "Primo").order(created_at: :desc)
cake_eater_nom << primo_cakes
multilayered_cakes = c.where(type: "Multilayered").order(created_at: :desc) 
cake_eater_nom << multilayered_cakes
decorative_cakes = c.where(type: "Decorative").order(created_at: :desc) 
cake_eater_nom << decorative_cakes
on_sale_cakes = c.where(type: "On Sale").order(created_at: :desc)
cake_eater_nom << on_sale_cakes
basic_cakes = c.where(type: "Basic").order(created_at: :desc)
cake_eater_nom << basic_cakes
ruby-on-rails ruby activerecord sql-order-by
2个回答
0
投票

您可以添加额外字段来存储您需要的订单,或使用

CASE WHEN
+
created_at
编写自定义条件。

order_sql = Arel.sql(
  "CASE WHEN type = 'Primo' THEN 0 " \
    "WHEN type = 'Multilayered' THEN 1 " \
    "WHEN type = 'Decorative' THEN 2 " \
    "WHEN type = 'On Sale' THEN 3 " \
    'ELSE 4 END, created_at'
)
@cakes = @store.cakes.order(order_sql)

0
投票

您可以将类型映射为整数并按如下所示进行排序

@cakes = @store.cakes.order(
  "CASE type WHEN 'Primo' THEN 1 WHEN 'Multilayered' THEN 2 WHEN 'Decorative' THEN 3 WHEN 'On Sale' THEN 4 ELSE 5 END"
  "created_at DESC"
)

您还可以在模型中以这种方式定义一些范围并应用它

# In the Cake model
scope :order_by_type_and_created_at_desc, ->() do
  order(
    <<~SQL,
      CASE type
      WHEN 'Primo' THEN 1
      WHEN 'Multilayered' THEN 2
      WHEN 'Decorative' THEN 3
      WHEN 'On Sale' THEN 4
      ELSE 5
      END
    SQL
    "created_at DESC"
  )
end

# Apply that scope
@cakes = @store.cakes.order_by_type_and_created_at_desc

另一种选择是保留数据库中的整数类型并使用枚举

# Enum
enum type: { primo: 1, multilayered: 2, decorative: 3, on_sale: 4, basic: 5 }

# Scope
scope :order_by_type_and_created_at_desc, ->() { order(type: :asc, created_at: :desc) }

注意:

type
是用于STI(单表继承)的保留字

© www.soinside.com 2019 - 2024. All rights reserved.