Requête sql dynamique - Ruby/Rails - Programmation
Marsh Posté le 08-11-2008 à 19:23:36
Salut,
Personnellement j'ai résolu ça de la manière suivante :
Code :
|
En gros, je garde la syntaxe avec le ? pour éviter les injections SQL. Mais afin d'éviter qu'on me joue des tours en détournant le nom des champs sur lesquels j'effectue mes recherches, je check qu'ils appartiennent aux champs définis dans le Model en question (lignes 15-18)
Marsh Posté le 23-01-2009 à 15:58:41
Quelqu'un a des bonnes sources et des tutoriaux sur la "reflection", parce qu'en fait avant je faisais comment vous, mais c'est super crado. J'arrive pas à invoquer des méthodes dynamiquement à la suite comme par exemple:
User.find_by_login(login).valid.author
Comment ils font dans Rails? C'est tout des named_scope?
Marsh Posté le 23-01-2009 à 16:46:29
J'ai pas trop compris là question. Tu veux faire quoi exactement?
Marsh Posté le 23-01-2009 à 18:48:17
En fait générer dynamiquement une seule méthode et l'invoquer je sais faire:
Ce que j'arrive pas à faire c'est par exemple exécuter dynamiquement plusieurs méthodes les unes à la suite des autres:
Code :
|
ou
Code :
|
date, login et group sont des named_scope et je veux les invoquer de manière conditionelle si leur paramètre est passé. Faire une boucle avec la méthode send ne marche pas, car les méthodes sont exécutées indépendemment les unes des autres.
Marsh Posté le 23-01-2009 à 20:03:37
Si j'ai bien compris, ça devrait être dispo pour Rails 2.3 ou 3 : http://ryandaigle.com/articles/200 [...] pe-methods
Sinon si tu veux just dynamiquement générer des critères de recherche qui porte sur un seul model, tu peux faire comme ça:
Dans mon cas j'ai nécessairement une recherche par site
Code :
|
Dans mon controlleur, je l'appelle avec: User.super_finder(site_id, search). Donc si en paramètre de recherche je ne mets rien, ça me génère:
Code :
|
Si en paramètre je passe login et id, ça me génére dynamiquement:
Code :
|
C'est plus propre non?
La limite, c'est qu'il faut que les critères de recherche porte sur le même Model. Donc par exemple:
Code :
|
ça marche nickel. Mais par exemple si je dois ajouter un critère qui porte sur un champ d'une table jointe, ça ne marche plus, par exemple:
Code :
|
Dans ce cas il faut utiliser un named_scope, malheureusement je ne sais pas comment faire par exemple un truc du genre:
Code :
|
EDIT: le module NamedScope possède une méthode scoped qui m'a l'air importante pour ce que je veux faire. D'ailleurs dans le patch Rails pour les named_scope dynamique c'est ce qui est utilisé, j'ai regardé le code source:
http://api.rubyonrails.org/classes [...] Scope.html
http://github.com/rails/rails/comm [...] 287afe2b55
Marsh Posté le 23-01-2009 à 21:23:14
Sinon une manière fort élégante de faire cette fameuse recherche par critère et qui utilise scoped: http://railscasts.com/episodes/112-anonymous-scopes
Il est fort ce Ryan Bates, et j'aime bien regarder le code source de son site railscasts
Sinon pour exécuter des méthodes à la chaîne il y a la méthode Kernel#eval qui exécute un String comme si c'était du code Ruby, à utiliser avec beaucoup de précautions donc.
Marsh Posté le 23-01-2009 à 22:14:25
D'accord
Pour le moment j'avais jamais eu besoin, mais c'est clair ça peut le faire
Par contre, je suis contre l'utilisation de Kernel#eval .. à mon avis ça doit être vraiment utilisé en dernier ressort ..
Marsh Posté le 08-11-2008 à 14:42:20
Bonjour à tous,
J'aimerais réaliser un petit moteur de recherche pour mon site mais je fais fasse à un problème.
Pour ce moteur, plusieurs champs de recherche sont disponible. En fonction des champs remplit par l'utilisateur, ma requête évolue donc, et c'est la que le problème survient.
Je voulais utilisé la méthode classique:
User.find(:all, :conditions => ['name = ?', name])
Mais je ne vois pas comment fait évoluer cette méthode de manière dynamique afin de rentrer les conditions en fonction de mes champs.
Exemple:
Si le nom de l'utilisateur recherche et son sexe est remplit, je voudrais un truc du genre:
User.find(:all, :conditions => ['name = ? AND sexe = ?', name, sexe])
Mais comment faire cela dynamiquement ?
J'ai essayé avec sql_conditions, mais visiblement, ça ne marche pas très bien avec la méthode que j'ai utilisé:
sql_conditions << [' AND sexe = ? ', @sexe] if !@sexe.nil?
sql_conditions << [' AND name = ? ', @name]
Il me dit "can't convert Array into String".
Je veux utiliser les ? pour éviter les sql injections.
Quelqu'un peut il m'aider ?
Merci.