Rails ActiveRecord - effectuer des recherches sur Plusieurs Attributs
Je me suis mise en œuvre d'une fonction de recherche simple que doit vérifier une chaîne de caractères dans le nom d'utilisateur, nom et prenom. J'ai vu cette ActiveRecord méthode sur un vieux RailsCast:
http://railscasts.com/episodes/37-simple-search-form
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
Mais comment puis-je faire pour qu'il recherche pour le mot clé dans le nom, le nom et prénom et retourne l'enregistrement si l'un des champs appariés le long terme?
Je me demande aussi si le code sur le RailsCast est sujette à des injections SQL?
Merci beaucoup!
Vous devez vous connecter pour publier un commentaire.
J'ai supposé que le nom de votre modèle est un Modèle juste de le remplacer avec votre vrai nom du modèle lorsque vous faites la requête:
Au sujet de vos inquiétudes au sujet des injections SQL - deux extraits de code sont à l'abri des injections SQL. Tant que vous n'avez pas intégrer directement des chaînes dans votre clause where vous êtes très bien. Un exemple pour injection sujettes code serait:
params
plutôt que de simplementparams[:search]
et dans notre requête, nous utilisons"%#{params[:search]}%"
au lieu de"%#{search}%"
. Est-ce toujours immunitaire à des injections SQL?where(name: params[:name])
Model.where("x ILIKE :query OR y ILIKE :query", query: "%#{params[:query]}%")
Bien que la réponse sélectionnée travaillera, j'ai remarqué qu'il se casse si vous essayez de taper une recherche "Raul Riera" parce qu'il va échouer sur les deux cas, parce que Raul Riera n'est pas mon prénom ou mon nom de famille.. c'est mon nom et prénom... je l'ai résolu en faisant
ILIKE
plutôt que downcase? Laissez la DB de la gérer.Avec Arel, vous pouvez éviter d'écrire du SQL manuellement avec quelque chose comme ceci:
Cela serait particulièrement utile si la liste des champs pour le match contre a été dynamique.
La meilleure façon de le faire est:
Plus de solution générique pour la recherche dans tous les champs du modèle serait comme cette
Ou mieux comme un champ d'application dans le modèle lui-même
Vous suffit de l'appeler comme cela
Avant de vous lancer.., non, sql injection, ne serait probablement pas de travail ici, mais encore mieux et plus court