2011-01-02 7 views
0

Je suis conscient que je peux rechercher des requêtes en appelant where() sur un modèle comme suit: Post.where(:title => 'My First Post')Comment effectuer une recherche dans Rails3?

Cependant, si je ne sais pas si l'utilisateur veut filtrer les paramètres de recherche? Par exemple, j'ai un formulaire de recherche qui a un champ optionnel title. Si le titre est rempli, le formulaire doit rechercher un titre. Si ce n'est pas le cas, cependant, le formulaire devrait juste retourner tous les champs.

J'ai essayé de faire quelque chose le long des lignes de

search = Post.all 
if params[:title].present? 
    search.where(:title => params[:title]) 
end 

Cependant, Rails retourne immidiately le résultat de la recherche quand je l'appelle Post.all et je ne peux plus ajouter des conditions/

Comment puis-je faire ce?

Merci!

Répondre

1

.all est une méthode de 'finisher' pour arel et provoque l'appel de la requête (même chose vaut pour .each et .first). Donc, si vous voulez être en mesure de construire la portée conditionnellement, .all devrait être la dernière chose appelée, si vous voulez l'appeler du tout.

+0

Alors comment puis-je obtenir la ressource sans récupérer les champs afin que je puisse continuer à appeler des conditions sur elle? Merci! –

+0

Une option consiste à définir 'search = Post.unscoped' ou' search = Post.scoped' qui vous laissera avec une relation arel pour jouer avec. Vous pouvez également repenser la façon dont vous ajoutez des étendues de manière conditionnelle et essayer de les traiter plus élégamment dans le modèle. – idlefingers

1

Étant donné qu'il n'y a vraiment pas grand-chose de la manière des relations à la chaîne ici, il semblerait qu'un simple-liner avec un opérateur ternaire peut faire:

@posts = params[:title].present? ? Post.where(:title => params[:title]) : Post.all 

... parce que quand il est non: où la portée de la clause, vous ne pourriez plus le chaîner à: all, de toute façon.

+0

Bien, mais c'était juste un exemple. Imaginez que je devrais appeler 5 conditions différentes ici en fonction de l'entrée de l'utilisateur. Comment puis-je obtenir une ressource sans appeler '.all' pour continuer à appeler des conditions? Merci! –

+0

Okay. Vous pouvez donc commencer par post_query = Post.scoped, puis construire au-dessus de cette portée de base, par exemple. post_query = post_query.where (: title => params [: title]) etc – Scott

Questions connexes