Вопрос по escaping, sanitize, tsvector, ruby-on-rails – Ruby on Rails: как санировать строку для SQL, когда не используется find?

12

Я пытаюсь очистить строку, которая включает в себя ввод данных пользователем, не прибегая к ручному созданию собственного, возможно, ошибочного регулярного выражения, если это возможно, однако, если это единственный способ, я также был бы признателен, если бы кто-нибудь мог указать мне правильное направление на регулярное выражение, которое вряд ли что-то упустит. В 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

Кажется, это проблема, вызванная отсутствием точек с запятой, и я могу вручную установить vector = '::' штраф.

У меня также была блестящая идея, возможно я могу просто назвать что-то вроде:

ActiveRecord::Base.connection.execute "UPDATE medias SET vectors = ? WHERE id = 1", "::"

Однако этот синтаксис не работает, потому что необработанные команды SQL не имеют доступа к методу экранирования и вводу строк при помощи символа? отметка.

Это вызывает у меня ту же проблему, что и вызов connection.execute для любого типа пользовательского ввода, поскольку все сводится к очистке строк, но я не могу найти какой-либо способ вручную вызывать методы очистки строк SQL в Rails. Кто-нибудь может дать какой-нибудь совет?

Ваш Ответ

1   ответ
15

Добавьте этот метод к вашей модели:

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

Теперь вы можете выполнить любой SQL, такой как:

Media.execute_sql('UPDATE medias SET vectors = ? WHERE id = 1', '::')

Ссылка

1)sanitize_sql_array

Спасибо за совет, работал именно так, как вы сказали. К сожалению, однако, похоже, что Rails не очищает двоеточия (:) для SQL на самом деле, и я все еще получаю ошибки в этой строке. Возможно, необходимость в санации толстой кишки уникальна для цвекторов. Похоже, мне придется идти по скрипучему маршруту регулярных выражений. William Jones

Похожие вопросы