rails active sql ruby-on-rails sanitize

active - Cómo desinfectar el fragmento sql en Rails



rollback migration rails (5)

Tengo que desinfectar una parte de la consulta SQL. Puedo hacer algo como esto:

class << ActiveRecord::Base public :sanitize_sql end str = ActiveRecord::Base.sanitize_sql(["AND column1 = ?", "two''s"], '''')

Pero no es seguro porque expongo el método protegido. ¿Cuál es una mejor manera de hacerlo?


A partir de los rieles 5, la forma recomendada es usar: ActiveRecord::Base.connection.quote(string)

como se indica aquí: https://github.com/rails/rails/issues/28947

ActiveRecord::Base::sanitize(string) está en desuso


ActiveRecord :: Base.connection.quote hace el truco en Rails 3.x


Esta pregunta no especifica que la respuesta debe provenir de ActiveRecord ni especifica para qué versión de Rails debe estar. Por esa razón (y porque es una de las mejores y pocas) respuestas sobre cómo desinfectar los parámetros en Rails ...

Aquí una solución que funciona con Rails 4:

En ActiveRecord::Sanitization::ClassMethods tiene sanitize_sql_for_conditions y sus otros dos alias : sanitize_conditions y sanitize_sql . Los tres hacen literalmente exactamente lo mismo.

sanitize_sql_for_conditions

Acepta una matriz, hash o cadena de condiciones SQL y las desinfecta en un fragmento SQL válido para una cláusula WHERE .

También en ActiveRecord tienes

sanitize_sql_for_assignment que

Acepta una matriz, hash o cadena de condiciones de SQL y las desinfecta en un fragmento SQL válido para una cláusula SET .

  • Los métodos anteriores se incluyen en ActiveRecord :: Base de manera predeterminada y, por lo tanto, se incluyen en cualquier modelo de ActiveRecord .

Además, en ActionController tienes ActionController::Parameters que te permite

elegir qué atributos deben incluirse en la lista blanca para la actualización masiva y así evitar la exposición accidental de lo que no debe exponerse. Proporciona dos métodos para este propósito: requerir y permitir .

params = ActionController::Parameters.new(user: { name: ''Bryan'', age: 21 }) req  = params.require(:user) # will throw exception if user not present opt  = params.permit(:name)  # name parameter is optional, returns nil if not present user = params.require(:user).permit(:name, :age) # user hash is required while `name` and `age` keys are optional

La "magia de los parámetros" se llama Parámetros fuertes ( aquí los documentos ) y puede usar eso para desinfectar los parámetros en un controlador antes de enviarlo a un modelo.

  • Los métodos anteriores están incluidos por defecto en ActionController::Base y, por lo tanto, están incluidos en cualquier controlador de Rails .

Espero que eso ayude a cualquiera, ¡solo para aprender y desmitificar a Rails! :)


Puede omitir el valor protected del método invocando indirectamente:

str = ActiveRecord::Base.__send__(:sanitize_sql, ["AND column1 = ?", "two''s"], '''')

... que al menos le ahorrará tener que remodelar ese método como public .

(Soy un poco sospechoso de que realmente necesites hacer esto, pero lo anterior funcionará).


Puedes simplemente usar:

ActiveRecord::Base::sanitize(string)