Skip to content

Instantly share code, notes, and snippets.

@tk0miya
Created June 14, 2022 16:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tk0miya/5e549172e478902ff683304da1c00ced to your computer and use it in GitHub Desktop.
Save tk0miya/5e549172e478902ff683304da1c00ced to your computer and use it in GitHub Desktop.
# frozen_string_literal: true
module Ransack
module Nullable
# Ransack で NULL を含む IN クエリを組み立てるためのヘルパ
#
# 利用方法:
# Ransack::Nullable.build(User, params[:q], nullable: %i[user_id])
#
# 注意点:
# * フォーム上では NULL を表す値として 'NULL' を送信すること
# * FormBuilder#collection_check_boxes() を使う場合、チェックボックスの値には String 型を用いること
def build(object, params, nullable: []) # rubocop:disable Metrics/MethodLength
queries = {}
# *_in 条件を抜き出す
nullable.each do |column|
key = "#{column}_in"
queries[key] = params.delete(key)
end
q = object.ransack(params)
queries.compact.each do |column, values|
# 抜き出した *_in 条件を再度組み立てる
if values.include? 'NULL'
# null を含む場合は (column IN (...) OR column IS NULL) に変換する
# 参考: https://github.com/activerecord-hackery/ransack/issues/290
null_column = column.sub(/_in$/, '_null')
q.build_grouping({ :m => 'or', column => values.grep_v('NULL'), null_column => true })
else
# null を含まない場合は通常通り column IN (...) に変換する
q.build_grouping({ column => values })
end
# FormBuilder#collection_check_boxes で扱いやすいよう、q.column_in 属性で入力値を返す
q.define_singleton_method(column) { values }
end
q
end
module_function :build
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment