您如何使用 LIKE 查询 rails 中的枚举?

How do you use LIKE query for enum in rails?

我已将枚举 task_status 设置为:

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

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

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

但这给了我错误

ActiveRecord::StatementInvalid (PG::UndefinedFunction: ERROR: operator does not exist: integer ~~ unknown) LINE 1: ...asks".* FROM "confirmed_tasks" WHERE (task_status like '%pen... ^ HINT: No operator matches the given name and argument types. You might need to add explicit type casts.

有什么建议吗?

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

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

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

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

这意味着您必须确定哪些标签符合您在应用程序级别的标准。然后将它们转换成它们的整数值(在数据库中使用)。实现此目的的一种方法是使用符合您要求的 grep in combination with a 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(&:to_sym).

的符号中