ruby-on-rails - matches_any 在使用 Arel 为数据表编写自定义过滤器的空数组上抛出异常

标签 ruby-on-rails activerecord arel

我正在使用 Ruby on Rails,使用 ajax-datatables-rails gem 来处理需要自定义过滤器的数据表。

我当前的过滤器如下所示:

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

产生错误

不支持的参数类型:NilClass。而是构造一个 Arel 节点。

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

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

最佳答案

查询“状态与空数组匹配”是不明确的,根据您的用例,它可能意味着几件事,您可能想要:

  • 匹配所有可能的状态
  • 根本不匹配任何行
  • 匹配具有 NULL 状态的行
  • 匹配除 NULL 之外的所有可能状态

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

  • 不添加过滤器(或1=1)
  • 过滤掉所有内容(或1=0)
  • 状态为空
  • 状态不为空

关于ruby-on-rails - matches_any 在使用 Arel 为数据表编写自定义过滤器的空数组上抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61687348/

相关文章:

mysql - Openshift 中 RoR Mysql 部署的问题

ruby-on-rails - 使用 Rails 开发时未更新 Javascript 文件

ruby-on-rails-3 - before_destroy 回调中未加载关联

mysql - 使用 Padrino + mysql 设置多个数据库

mysql - Rails Arel 通过连接表上的 where 条件进行连接

ruby-on-rails - 如何调试/修复随机发生的 Redis::TimeoutError?

javascript - ExecJS::ProgramError:意外字符 '#'

ruby-on-rails - 渲染联接模型及其关联模型的JSON对象

ruby-on-rails - 如何在 Rails 4 中合并(链接)2 个不同表上的关系

ruby-on-rails - Rails 根据字段值更新多个记录