您需要使用Postgres JSON 函数来查询 JSON 列 audited_changes 而不是 LIKE 运算符。
step_id
要查找更改的审核,您可以使用
.where("(audited_changes -> 'step_id')::jsonb ? :step_id", step_id: '9')
注意使用命名绑定变量 :step_id
,而不是使用活动记录问号 ( ?
) 替换,因为 Postgres 使用问号作为 JSON 查询运算符。
上面的子句将找到任何审计step_id = 9
,无论是在先前版本中设置的值还是模型的更新版本中设置的值。
step_id = 9
要查找以前版本中的审核:
# Check if the first value (indexed by 0) in 'step_id' array is '9'
.where("(audited_changes -> 'step_id')::jsonb->0 ? :step_id", step_id: '9')
step_id = 9
要在更新版本中查找带有 set 的审计:
# Check if the second value (indexed by 1) in 'step_id' array is 9
.where("(audited_changes -> 'step_id')::jsonb->1 ? :step_id", step_id: '9')
(注意:您不应该直接对 where 子句的条件进行字符串插值,因为您将应用程序打开到SQL 注入漏洞。请改用带有经过清理的输入的 rails 样式条件。)
编辑
由于您已指示您的 audited_changes 列类型是 TEXT 而不是 JSON 类型,因此您将需要运行迁移以更改列类型或在查询中转换列。
要在查询执行时将列转换为 JSON,请使用audited_changes::json
,因此示例如下所示:
.where("(audited_changes::json -> 'step_id')::json ? :step_id", step_id: '9')
要将列更改为 JSON,请以rails g migration ChangeAuditedChangesColumnToJSONB
. 然后在您的迁移文件 ( db/migrate/{timestamp}_change_audited_changes_column_to_jsonb.rb
) 中写入:
class ChangeAuditedChangesColumnToJSONB < ActiveRecord::Migration[5.1]
def up
change_column :audits, :audited_changes, :jsonb, using: 'audited_changes::JSONB'
end
def down
change_column :audits, :audited_changes, :text
end
end
然后运行rails db:migrate
,你应该很高兴。
对于使用 Audited 的新项目,您可以在安装步骤中添加一个参数,以指定对 audited_changes 列使用 JSON 或 JSONB 类型。
rails generate audited:install --audited-changes-column-type jsonb # or json