Rails
sort
enum

enumを任意の順番に並び替え(ソート)する方法

例えば、以下のenumが定義されているとします。


class Post < ApplicationRecord
enum category: { game: 10, beauty: 20, gadget: 30 }
end

これを、beauty(20) → game(10) → gadget(30)の順番で並び替えたいとする場合、以下のようにスコープを作ってあげればOK。

CATEGORY_ORDERS = [20, 10, 30]

scope :order_by_category, -> {
order_by = []
CATEGORY_ORDERS.each { |category| order_by << "category=#{category} DESC" }
order(order_by.join(", "))
}


> Post.order_by_category

するとSQLはこんな感じになります。


SELECT `posts`.* FROM `posts` ORDER BY category=20 DESC, category=10 DESC, category=30 DESC

順番を変えたくなったら、定数を変更するだけで済むので割と便利かなと。(頻繁に変える場合は変数にすべきですが。。)

参考: https://stackoverflow.com/questions/37599510/custom-order-based-on-enum-values


追記

配列に対してソートする場合、field関数を使った方が簡潔にできるようです!


CATEGORY_ORDERS = [20, 10, 30]

scope :order_by_category, -> {
order(["field(category, ?)", CATEGORY_ORDERS])
}


SELECT `questions`.* FROM `questions` ORDER BY field(category, 20,10,30)

調べてくださった@scivolaさん、@QUANONさん、ありがとうございました!

参考: https://qiita.com/chezou/items/8c0481044c954c4bca3b