Rails审核了搜索

时间:2017-08-14 13:27:13

标签: ruby-on-rails postgresql acts-as-audited

我正试图找到去年已经设置为特定状态的所有项目。 我正在使用Rail 5进行审计,因此我创建了一个特定的审计模型,并尝试编写一个范围来恢复我的条件:

import speech_recognition as sr

r = sr.Recognizer()
with sr.Microphone() as source:
    print("Say something!")
    audio = r.listen(source)

# Speech recognition using Google Speech Recognition
try:
    print("You said: " + r.recognize_google(audio))
except sr.UnknownValueError:
    print("Google Speech Recognition could not understand audio")
except sr.RequestError as e:
    print("Could not request results from Google Speech Recognition service; {0}".format(e))

postgres中的审核文本字段的内容在我接受时显示为Audit = Audited.audit_class class Audit scope :followupRebus, -> { where(auditable_type: 'Followup') .where(action: 'update') .where("audited_changes LIKE '%step_id:[#{Step::REBUS}%'") } end

.to_s

如何使用{"step_id"=>[9, 4], "active"=>[false, true]} 进行所有审核?

修改

非常感谢DRSE,我终于找到了一个有效的解决方案:

  1. 使用DRSE发送的迁移更改列的默认TEXT类型
  2. 像这样更改请求:

    班级审核   范围:followupRebus, - > {where(auditable_type:'Followup')     .where(动作:'更新')     .where(“((audited_changes - >'step_id'):: json->> 0):: int =:step_id”,step_id:Step :: REBUS)   }

1 个答案:

答案 0 :(得分:3)

您需要使用Postgres JSON functions来查询JSON列audited_changes而不是LIKE运算符。

要查找step_id已更改的位置的审核,您可以使用

.where("(audited_changes -> 'step_id')::jsonb ? :step_id", step_id: '9')

请注意使用named bind variable :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的审核:

# 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 injection vulnerability。请改用rails style conditions with sanitized inputs。)

修改

由于您已指示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的新项目,您可以add a param to the install step为audited_changes列指定使用JSON或JSONB类型。

rails generate audited:install --audited-changes-column-type jsonb # or json