Last active
February 19, 2021 10:33
-
-
Save nagait84/bb89d514ca0722532d8d660868163f8e to your computer and use it in GitHub Desktop.
【Rails】PostgreSQLでORDER BY FIELD句を実現したい
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# @note Concern扱いではなく、#extendingとして使用 | |
module DmlSanitizable | |
# PostgreSQL使用時に、MySQLの `ORDER BY FIELD()` 関数と同じ挙動をさせる | |
# @example | |
# models = Model.all.extending(DmlSanitizable) | |
# models.order_by_field(:color, ['緑', '紫', '赤', '青', '黄'], :desc) | |
# # => [#<Model color: '黄'>, #<Model color: '青'>, #<Model color: '赤'>, ...] | |
# @param column [Symbol] | |
# @param custom_list [Array] 並び替えたい値の順序 | |
# @param sort_order [Symbol(:asc), Symbol(:desc)] (:asc) 昇順or降順 | |
# @return [Model::ActiveRecord_Relation] Modelは#extending先のモデルクラス | |
def order_by_field(column, custom_list, sort_order = :asc) | |
return self if custom_list.blank? | |
model = self.class.to_s.deconstantize.constantize | |
num = custom_list.length | |
dml = <<~DML.squish | |
CASE #{column} | |
#{(0...num).map { |i| "WHEN ? THEN #{i}" }.join("\n")} | |
ELSE #{num} | |
END | |
#{sort_order.upcase} | |
DML | |
order( | |
# FIXME: Rails4系だったのでsend使っているがそのままsanitize_sql_array()宣言で良い | |
model.send(:sanitize_sql_array, [dml, *custom_list]) | |
) | |
end | |
end |
こちら custom_list
が空配列の場合にバグるので要修正。
https://gist.github.com/nagait84/bb89d514ca0722532d8d660868163f8e#gistcomment-3637163
こちら
custom_list
が空配列の場合にバグるので要修正。
こちら修正しました
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://qiita.com/nagait84/items/b1b58608f812d77e18c4