Skip to content

Instantly share code, notes, and snippets.

@gouf
Created December 27, 2018 02:11
Show Gist options
  • Save gouf/8d673a437f7ed23fa22fb8e051617ba7 to your computer and use it in GitHub Desktop.
Save gouf/8d673a437f7ed23fa22fb8e051617ba7 to your computer and use it in GitHub Desktop.
key / value な形式で送られてきた値を Model#where で検索できる形式に変換する
# 次のコードで登場する User モデルの各定数には Hash で値が代入されている + コントローラやビューで <form/> の値として使われている
# eg. FROZEN_FRUITS = {'0' => 'Apple', '1' => 'Banana'}.freeze
# values にはUser モデルの定数に定義された value 側の値が代入されている
# eg. ['Apple', 'Banana']
# 呼び出し元はループ処理でこのメソッドを呼び出して、最終的に 条件群、パラメータ群の配列に纏めている
# コントローラ内で分解された params 内の Hash から Model#where で検索できる値のペアを生成する
def params_to_sql_fragment(field, values)
# 指定された配列の値をもとに、モデルに定義された Hash 型定数の key 値を取り出す
fetch_const_keys_from_values =
lambda do |values, const|
values.map do |value|
const.find_all { |_k, v| v.eql?(value) }
.map { |k, _v| k }
end.flatten
end
# 検索値の数に合わせたプレースホルダ「?」配列に加え、それに対応した検索値を返す
build_the_in_query_value_pair =
lambda do |values, const|
if values.first.empty?
[
# 特に検索値が指定されない場合、全項目検索に切り替え
Array.new(const.keys.size, '?').join(', '),
const.keys
]
else
[
Array.new(values.size, '?').join(', '),
fetch_const_keys_from_values.call(values, const)
]
end
end
case field
when 'users.admin_role' # 管理者
placeholders, parameter =
build_the_in_query_value_pair.call(values, User::ADMIN_ROLES)
[["users.admin in (#{placeholders})"], parameter]
when 'users.some_other_role' # その他属性
placeholders, parameter =
build_the_in_query_value_pair.call(values, User::SOME_OTHER_ROLES)
[["users.some_other in (#{placeholders})"], parameter]
else # 該当無しは like 検索できるセットを返す
[["#{field} like ?"], ["%#{values}%"]]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment