Question

DocumentsController # common_query peut gérer plusieurs styles de requête différents.

i.e. tous les documents du lot 4 ou tous les documents étiquetés "heureux"

Je veux un seul itinéraire pour les rendre jolies, alors:

/ documents / common_query? batch = 4

/ documents / common_query? tag = content

devenir:

/ documents / batch / 4

/ documents / tag / happy

Le résultat final est donc que #common_query est appelé mais qu'une partie de l'URL a été utilisée comme nom de paramètre et une partie comme valeur.

Était-ce utile?

La solution

Comme un seul itinéraire:

ActionController::Routing::Routes.draw do |map|
  map.connect "documents/:type/:id", :controller => "documents_controller", 
              :action => "common_query"
end

Alors params [: type] sera soit "batch" , soit "tag" , et params [: id] "4" ou "heureux" . Vous devrez vous assurer que les autres actions pour DocumentsController viennent avant cela dans les routes, car elles correspondront à toutes les URL qui ressemblent à " documents / * / * & <; code>. .

Mais pourquoi faut-il que ce soit un seul itinéraire? Vous pouvez utiliser deux itinéraires comme ceci:

map.with_options(:controller => "documents_controller", 
                 :action => "common_query") do |c|
  c.connect "documents/batch/:page", :type => "batch"
  c.connect "documents/tag/:tag",    :type => "tag"
end

qui aura le même effet, mais sera plus spécifique, vous ne devrez donc pas vous soucier de l'ordre de priorité des itinéraires.

Autres conseils

La deuxième option, avec deux itinéraires, est presque certainement la meilleure solution, car elle ne correspond qu'aux types d'URL que vous souhaitez prendre en charge, tandis que la première option permet également de "faire correspondre" les informations. Des URL telles que / documents / foo / bar, qui entraîneront probablement, au mieux, votre méthode #common_query à renvoyer une réponse RecordNotFound (404). Au pire, si vous n'êtes pas prêt à ne voir aucun de vos paramètres attendus, vous obtiendrez une erreur 500 à la place ...

Bien sûr, si vous commencez à avoir beaucoup de variations, vous vous retrouverez avec beaucoup de routes. Et si vous devez les utiliser en même temps, par exemple, / documents / batch / 4 / tag / happy, vous devrez utiliser un itinéraire générique et effectuer le traitement des paramètres dans votre contrôleur. Cela pourrait ressembler à quelque chose comme:

map.connect 'documents/*specs', :controller => "documents_controller", :action => "common_query"

Les différents éléments de l’URL seront disponibles dans votre contrôleur en tant que params [: specs]. Vous pouvez transformer cela en une trouvaille comme celle-ci:

@items = Item.find(:all, :conditions => Hash[params[:specs]])

Cette technique de hachage [] convertit le tableau unidimensionnel d'options en un hachage valeur-clé, ce qui peut s'avérer utile même si vous ne le transmettez pas directement à find ().

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top