matches_any在空数组上引发异常,使用Arel为数据表编写自定义过滤器

问题描述 投票:0回答:1

我正在使用ajax-datatables-rails gem用于需要定制过滤器的数据表来使用Ruby on 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')"

如果该数组导致异常,则对模型运行.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.

处理matches_any中的空数组的正确方法是什么?我也可以在没有球的情况下做到这一点。状态只是模型上的一列

编辑:进一步的背景,UI端的此数据表具有一个搜索框,并且此字段的文本在显示内容和数据库实际内容之间有所不同。此自定义过滤器从数据库中获取不同的值,并将视图文本映射到有意义的数据库文本。它“喜欢”所查看的文本,从数据库端获取匹配项,并且需要不断应用过滤器。因此,视图文本上的部分匹配与实际数据库匹配相匹配。这意味着可能没有数据库匹配项和match_any? that。

ruby-on-rails activerecord arel
1个回答
1
投票

查询“状态匹配一个空数组”是模棱两可的,取决于您的用例,这可能意味着几件事,您可能想要:

  • 匹配所有可能的状态
  • 完全不匹配任何行
  • 匹配具有NULL状态的行
  • 匹配NULL以外的所有可能状态

因此,您应检查statuses是否为空,并返回与您要执行的操作匹配的查询。要么:

  • 不添加过滤器(或1=1
  • 过滤出所有内容(或1=0
  • status IS NULL
  • status IS NOT NULL
© www.soinside.com 2019 - 2024. All rights reserved.