Match_any генерирует исключение для пустого массива, записывая пользовательский фильтр для Datatables с использованием Arel - PullRequest
2 голосов
/ 08 мая 2020

Я работаю с Ruby на Rails, используя гем ajax -datatables-rails для таблиц данных, для которых мне нужен настраиваемый фильтр.

Мой текущий фильтр выглядит так:

def filter_status_column
  statuses = []
  ->(column, value) do
    # Do stuff and put statuses in the array
    ::Arel::Nodes::SqlLiteral.new(column.field.to_s).matches_any(statuses)
  end
end

Это, когда мой массив не пуст, будет генерировать некоторые sql вроде этого:

0> ::Arel::Nodes::SqlLiteral.new(column.field.to_s).matches_any(like_mapped_values).to_sql
=> "(status ILIKE 'Foo' OR status ILIKE 'Bar')"

Если array, это вызывает исключение, которое, как я ожидал, после запуска .where("status in ?", []) для модели выглядит следующим образом, поскольку он превращает [] в null:

"(status ILIKE NULL)"

Вызов

::Arel::Nodes::SqlLiteral.new(column.field.to_s).matches_any([]).to_sql

генерирует ошибку

Unsupported argument type: NilClass. Construct an Arel node instead.

Каков правильный метод обработки пустого массива в match_any? Полагаю, я мог бы сделать это и без арела. Статус - это просто столбец на модели

РЕДАКТИРОВАТЬ: Дополнительная информация, эта таблица данных на стороне пользовательского интерфейса имеет поле поиска, и это поле отличается по тексту между тем, что отображается, и тем, что на самом деле находится в базе данных. Этот настраиваемый фильтр берет отдельные значения из базы данных и сопоставляет текст представления с осмысленным текстом базы данных. Ему "нравится" просматриваемый текст, он берет совпадение со стороны базы данных и должен применять фильтры по мере его поступления. Таким образом, частичное совпадение в тексте представления совпадает с фактическим совпадением в базе данных. Это означает, что совпадений в базе данных быть не может и match_any? рвет на этом.

1 Ответ

3 голосов
/ 12 мая 2020

Запрос «статус соответствует пустому массиву» неоднозначен, в зависимости от вашего варианта использования это может означать несколько вещей, вы можете захотеть:

  • сопоставить все возможные статусы
  • не соответствует ни одной строке
  • соответствует строкам, имеющим NULL статус
  • соответствует всем возможным статусам, кроме NULL

Поэтому вам следует проверить, statuses пусто и возвращает запрос, соответствующий тому, что вы хотели бы сделать. Либо:

  • без добавления фильтра (или 1=1)
  • отфильтровать все (или 1=0)
  • status IS NULL
  • status IS NOT NULL
...