Je dois nettoyer une partie de la requête SQL. Je peux faire quelque chose comme ça:
class << ActiveRecord::Base
public :sanitize_sql
end
str = ActiveRecord::Base.sanitize_sql(["AND column1 = ?", "two's"], '')
Mais ce n'est pas sûr parce que j'expose la méthode protégée. Quelle est la meilleure façon de le faire?
Vous pouvez simplement utiliser:
ActiveRecord::Base::sanitize(string)
ActiveRecord::Base.connection.quote
fait le tour dans Rails 3.x
Cette question ne spécifie pas que la réponse doit provenir de ActiveRecord
et ne précise pas non plus quelle version de Rails elle devrait être. Pour cette raison (et parce que c’est l’un des meilleurs), on explique comment assainir les paramètres dans Rails ...
Voici une solution qui fonctionne avec Rails 4:
Dans ActiveRecord::Sanitization::ClassMethods
, vous avez sanitize_sql_for_conditions et ses deux autres alias): sanitize_conditions et sanitize_sql. Les trois font littéralement exactement la même chose.
sanitize_sql_for_conditions
Accepte un tableau, un hachage ou une chaîne de conditions SQL et désinfecte les dans un fragment SQL valide pour une clause WHERE.
Aussi dans ActiveRecord vous avez
sanitize_sql_for_assignment
qui
Accepte un tableau, un hachage ou une chaîne de conditions SQL et les assainit dans un fragment SQL valide pour une clause SET.
Voir docs
Cependant, dans ActionController, vous avez ActionController::Parameters
qui vous permet de
choisissez quels attributs doivent être ajoutés à la liste blanche pour la mise à jour en masse et évitez donc d'exposer accidentellement ce qui ne devrait pas être exposé . Fournit deux méthodes à cette fin: require et permit.
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 "magie des paramètres" s’appelle Strong Parameters ( docs here ) et vous pouvez l’utiliser pour nettoyer les paramètres dans un contrôleur avant de l’envoyer à un modèle.
ActionController::Base
et sont donc incluses dans tout contrôleur Rails.J'espère que cela aidera n'importe qui, ne serait-ce que pour apprendre et démystifier Rails! :)
Vous pouvez contourner la valeur protected
ness de la méthode en appelant indirectement:
str = ActiveRecord::Base.__send__(:sanitize_sql, ["AND column1 = ?", "two's"], '')
... ce qui vous évitera au moins de devoir refaire cette méthode en public
.
(Je suis un peu méfiant sur le fait que vous ayez réellement besoin de faire ça, mais ça va marcher.)
A partir de Rails 5, la méthode recommandée consiste à utiliser: ActiveRecord::Base.connection.quote(string)
comme indiqué ici: https://github.com/Rails/rails/issues/28947
ActiveRecord::Base::sanitize(string)
est obsolète
Notez que lorsqu'il s'agit de nettoyer les conditions SQL WHERE, la meilleure solution étaitsanitize_sql_hash_for_conditions , car elle gérait correctement les conditions NULL (par exemple, générerait IS NULL
au lieu de = NULL
si un attribut nil était passé).
Pour une raison quelconque, il était obsolète dans Rails 5. J'ai donc lancé une version à l'épreuve du futur, voir ici: https://stackoverflow.com/a/53948665/165673