Ruby on Rails:如何在不使用find时清理SQL的字符串?

Wil*_*nes 12 escaping ruby-on-rails sanitize tsvector

我正在尝试清理涉及用户输入的字符串,而不必在可能的情况下手动制作我自己的可能错误的正则表达式,但是,如果这是唯一的方式我也会感激如果有人能指出我正确的方向正则表达式不太可能遗漏任何东西.Rails中有许多方法可以让你输入本机SQL命令,人们如何逃避用户输入?

我问的问题很广泛,但在我的特殊情况下,我正在使用Postgres数据库中的一个专栏,据我所知,Rails本身并不理解tsvector,它包含纯文本搜索信息.Rails能够写入和读取它,就像它是一个字符串一样,但是,与字符串不同,当我在模型中执行vector =之类的事情时,它似乎并没有自动转义它.

例如,当我做model.name ='::',其中name是一个字符串,它工作正常.当我做model.vector ='::'时出错了:

ActiveRecord::StatementInvalid: PGError: ERROR:  syntax error in tsvector: "::"
"vectors" = E'::' WHERE "id" = 1
Run Code Online (Sandbox Code Playgroud)

这似乎是由于缺少分号的转义而导致的问题,我可以手动设置vector ='''罚款.

我也有一个好主意,也许我可以称之为:

ActiveRecord::Base.connection.execute "UPDATE medias SET vectors = ? WHERE id = 1", "::"
Run Code Online (Sandbox Code Playgroud)

但是,这种语法不起作用,因为原始SQL命令无法通过使用?来查找转义和输入字符串的方法.标记.

这与我用任何类型的用户输入调用connection.execute同样的问题,因为它归结为清理字符串,但我似乎无法找到任何方法手动调用Rails的SQL字符串清理方法.有人可以提供任何建议吗?

Har*_*tty 16

将此方法添加到您的模型:

class Media < ActiveRecord::Base
  def self.execute_sql(*sql_array)     
    connection.execute(send(:sanitize_sql_array, sql_array))
  end
end
Run Code Online (Sandbox Code Playgroud)

现在您可以执行任何SQL,例如:

Media.execute_sql('UPDATE medias SET vectors = ? WHERE id = 1', '::')
Run Code Online (Sandbox Code Playgroud)

参考

1)sanitize_sql_array