2010-11-20 7 views
2

J'ai un formulaire de recherche avec deux champs: x, yRails Trouver lorsque certains params seront vides

Lorsque la recherche est effectuée, il recherchera les enregistrements correspondant à toutes les conditions. Toutefois, l'une des deux conditions peut être définie sur "Tous" en laissant cette case vide.

Que dois-je régler params [: x] et params [: y] s'ils sont tous réglés.

params[:x] = ? unless params[:x] 
params[:y] = ? unless params[:y] 

users = User.where(["x = ? AND y = ?", params[:x], params[:y]]) 

Répondre

4

Je suggère la construction de vos conditions en utilisant un hachage:

conditions = {} 
conditions[:x] = params[:x] unless params[:x].blank? 
conditions[:y] = params[:y] unless params[:y].blank? 

users = User.find(:all, :conditions => conditions) 
+0

Cette méthode empêche-t-elle les intentions malveillantes comme la méthode ["x =? AND y =?", X, y]? – bmck

+0

Oui, la seule façon de ne pas protéger contre l'injection SQL est de mettre les chaînes directement dans les conditions. Cette instruction: "X = # {params [: x]}" est ouverte à l'injection SQL. Les instructions ["X =?", Params [: x]] et {: x => params [: x]} n'autorisent pas l'injection SQL. –

+1

* à la fois le tableau et les approches de hachage appeler la fonction de sanitize_sql: http://apidock.com/rails/ActiveRecord/Base/sanitize_sql/class –

4

Vous devez enchaîner vos conditions au lieu d'essayer de construire une portée si spécifique. Vous pouvez utiliser une technique de portée de glissement:

scope = User 

if (params[:x].present?) 
    scope = scope.where(:x => params[:x]) 
end 

if (params[:y].present?) 
    scope = scope.where(:y => params[:y]) 
end 

users = scope.all 

De cette façon, vous pouvez conditionnellement engager des restrictions en fonction des paramètres qui peuvent être présents.

+0

Merci pour l'explication! – dennismonsewicz

+0

@tadman, existe-t-il un moyen de faire ce qui précède dans Rails 2.3? Je travaille sur une application héritée avec des conditions qui comprennent LIKE et supérieures à/inférieures à des instructions. Merci! – KDP

+0

Dans Rails 2.3, vous pouvez le faire en ajoutant à l'argument 'conditions' que vous allez passer dans l'appel' find'. – tadman

Questions connexes