如何按字符串排序,Ruby

ne5o7dgx  于 12个月前  发布在  Ruby
关注(0)|答案(3)|浏览(101)

所以我有@cake.type,它可以是“Primo”,“Multilayered”,“Decorative”,“On销售”,“Basic”。
我想把蛋糕按这个顺序排列。所以所有的“Primo”蛋糕在顶部,其次是所有的“多层”蛋糕下一个等。每种类型的蛋糕应进一步列出“创建_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)

有没有一种方法可以用一个查询来完成?
. maybe:

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
jjjwad0x

jjjwad0x1#

如果你已经在使用Ruby on Rails 7.0,那么你可以像这样使用in_order_of

types = ['Primo', 'Multilayered', 'Decorative', 'On Sale', 'Basic']

@cakes = @store.cakes
               .where(type: types)
               .in_order_of(:type, types) # sort by type (from list) frist 
               .order(:created_at)        # then by created_at (oldest first)
5jdjgkvh

5jdjgkvh2#

您可以添加一个额外的字段来存储所需的顺序,或者使用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)
piwo6bdm

piwo6bdm3#

你可以用整数Map类型,并按它们排序,如下所示:

@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(单表继承)的保留字

相关问题