Skip to content

Instantly share code, notes, and snippets.

@nagait84
Last active February 19, 2021 10:33
Show Gist options
  • Save nagait84/bb89d514ca0722532d8d660868163f8e to your computer and use it in GitHub Desktop.
Save nagait84/bb89d514ca0722532d8d660868163f8e to your computer and use it in GitHub Desktop.
【Rails】PostgreSQLでORDER BY FIELD句を実現したい
# @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
@nagait84
Copy link
Author

こちら custom_list が空配列の場合にバグるので要修正。

@nagait84
Copy link
Author

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