Salut Patrick,
J’ai une requete find qui prend une variable en argument comme ca:
@catlist = “#{([“category_id = ?”] * subcats.size).join(” OR “)}”
Première remarque, ton écriture est plutôt compliqué et gagnerait Ã
être simplifié :
- String#join retourne une chaîne de caractères donc tu ne gagnes
à rien de créer une autre chaîne dans lequel tu ne fais uniquement
une substitution de chaîne. Si str est une chaîne, il y a peu
d’intérêt à faire “#{str}”.
Donc ça s’écrit : @catlist = ([“category_id = ?”] * subcats.size).join("
OR ")
Deuxièmement : tu utilises * et tu fais un join juste après, ce qui
t’obliges
de surcroît à utiliser des parenthèses, autant faire simple
et écrire :
@catlist = [“category_id = ?”] * subcats.size * " OR "
C’est plus lisible non ?
@values = @searchkeywords.join(",")
Ici, @values (mais au fait, as tu vraiment besoin d’avoir values
comme variable d’instance, tu t’en sers pour construire le find,
mais t’en as besoin dans ta vue ?) est une chaîne de caractères,
puisque tu fais un Array#join.
@ads = Ad.find(:all , :conditions => [
@catlist,"#{@values}"],:order=>“updated_on”)
Pour “#{@values}”, comme @values est une String, la remarque
en haut s’applique aussi ici.
avec @values=val1,val2,val3 etc
Ben non, @values=“val1,val2,val”, ie une chaîne de caractères
avec des virgules dedans, ce n’est pas la même chose
que : @values = [“val1”, “val2”, “val3”]
Le probléme c’est que rails voit @values comme une seul variable au
lieu de plusieurs. Est-ce qu’il y a un moyen que rails reconnaissent
@values comme plusieurs attributs?
D’abord pour adopter une terminologie commune, tu souhaites
que Ruby considère @values comme un tableau d’éléments (un
tableau de String même) plutôt qu’une String unique ; de plus,
quand on parle d’attributs pour un Modèle dans Rails, ça désigne
autre chose ça correspond au mapping colonnes de ta table <->
attributs de ton modèle.
Revenons-en à ta construction de ton find. option[:conditions]
doit être sous la forme d’un tableau bien spécifique :
tu écris [ @catlist, “#{@values}” ] qui est équivalent Ã
[@catlist, @values]
avec @values=“val1,val2,val3”, tu as en fait
[@catlist, “val1, val2, val3” ]. Ce que tu souhaites, c’est
[@catlist, “val1”, val2", val3"]. Tu dois plutôt manipuler
@values comme un tableau car :
- si tu as [“foo”, bar], avec bar un tableau, par exemple = %w(un deux)
tu as [“foo”, [“un”, deux"]] et il suffit d’appeler #flatten pour
obtenir
[“foo”, “un”, “deux”]
- autre solution, si tu as [“foo”] et bar = %w(un deux), tu peux
concaténer les deux tableaux [“foo”].concat(bar) pour encore obtenir
[“foo”, “un”, “deux”].
Ainsi [@catlist, @values] se transforme en
[@catlist].concat(@values) pour obtenir ce que tu souhaites avec
@values un tableau.
Or @values = “val1, val2, val3”. Facile, il suffirait d’utiliser #split
pour avoir un tableau ! Mais finalement, faire un join suivi d’un
split à partir de @searchkeywords qui est déjà un tableau (de String),
ça sert à quoi ?
Au final, ton code se simplifie en :
catlist = [“category_id = ?”] * subcats.size * " OR "
@ads = Ad.find(:all,
:conditions => [ catlist ].concat(@searchkeywords),
:order => “updated_on”)
(et si finalement tu avais besoin de catlist dans ta vue, tu remets les
@ )
A+
– Jean-François.