【问题标题】:How do you use LIKE query for enum in rails?你如何在 Rails 中使用 LIKE 查询枚举?
【发布时间】:2026-02-24 12:45:01
【问题描述】:

我已将枚举 task_status 设置为:

class ConfirmedTask < ApplicationRecord
  enum task_status: {pending: 1, complete: 2}
end

现在我必须使用搜索参数“挂起”来搜索所有处于挂起状态的任务。我正在使用 pg_search 进行搜索,但它不适用于枚举,所以我想使用 LIKE 查询进行查询:

ConfirmedTask.where('task_status like ?', '%pend%')

但这给了我错误

ActiveRecord::StatementInvalid (PG::UndefinedFunction: ERROR: 运算符不存在:整数~~未知)第 1 行:...asks".* FROM "confirmed_tasks" WHERE (task_status like '%pen... ^ 提示:没有运算符匹配给定的名称和参数类型。你可能需要 添加显式类型转换。

有什么建议吗?

【问题讨论】:

  • 看起来 enum 不适合您的用例。我建议要么删除枚举并存储实际的字符串值(待处理,完成),或者如果你使用枚举让 UI 提供完整值('待处理'而不是'待处理')

标签: ruby-on-rails ruby plpgsql pg-search


【解决方案1】:

枚举通常以整数形式存储在数据库中。到标签的映射是在应用程序级别完成的。数据库不知道标签。

这意味着您必须弄清楚哪些标签符合您的应用级别标准。然后将它们转换为它们的整数值(在数据库中使用)。实现此目的的一种方法是将grep 与符合您要求的regex 结合使用。

# find the matching labels
labels = ConfirmedTask.task_statuses.keys.grep(/pend/i)
# convert them into their integer values
values = labels.map(&ConfirmedTask.task_statuses)
# create your query
ConfirmedTask.where('task_status IN (?)', values)

更简单的方法是将标签放到值转换中,让 Rails 解决这个问题。这可以通过将标签数组传递给普通的 where 调用(使用非 SQL 字符串参数)来完成。

# find the matching labels
labels = ConfirmedTask.task_statuses.keys.grep(/pend/i)
# pass labels to `where` and let Rails do the label -> integer conversion
ConfirmedTask.where(task_status: labels)

我不确定 100% 是否允许字符串数组作为枚举属性的 where 条件。 The documentation uses symbols。如果上述方法不起作用,请将字符串映射为带有.map(&amp;:to_sym) 的符号。

【讨论】:

    【解决方案2】:

    如果你想在这里使用枚举,那么你需要将你的枚举值作为字符串存储在数据库中。目前,您的列 task_status 具有 integer 类型。因此您无法使用 LIKE 运算符进行搜索。要解决它,请进行此更改。

      enum task_status: {pending: 'pending', complete: 'complete'}
    

    并将task_status 列的类型设置为数据库中的string。 但我建议您尽可能从前端发送值的全名。

    【讨论】: