web-dev-qa-db-fra.com

Comment utiliser Rails aides de route nommées avec des paramètres?

étant donné cet itinéraire

match 'posts/hello/:name/:title' => 'post#show', :as => :hello
  • comment puis-je appeler hello_path?

  • si j'appelle hello_path(@post), qu'est-ce qu'il essaie de faire?

J'espérais que les fichiers :name Et :title Se lieraient automatiquement au chemin, mais il semble que Rails sait seulement comment extraire le: id du objet modèle.

à la place, cela ne fonctionne que si je l'appelle comme

<%= link_to "link2", hello_url(:name=> @post.name, :title=>@post.title) %>

(le manque de documentation appropriée me tue vraiment)

29
Ant

Pour répondre à vos deux questions:

  • Sur la ligne de commande, exécutez rake routes Pour voir quels itinéraires existent dans votre application. Il vous montrera toutes les façons dont vous pouvez utiliser les routes nommées, il suffit d'ajouter "_path" ou "_url" au nom de la route qui apparaît à gauche.
  • L'appel de hello_path(@post) générera une URL vers la page show pour cette instance hello.

La façon dont vous l'appelez est la norme:

<%= link_to "link2", hello_url(:name=> @post.name, :title=>@post.title) %>

Cependant, cela peut aussi fonctionner:

<%= link_to "link2", hello_url(@post.name, @post.title) %>

Voici une documentation (autre que l'API Rails) qui devrait aider. http://guides.rubyonrails.org/routing.html

17
GregT

Pour répondre à votre question "qu'est-ce que hello_path essayer de faire?"

hello_path sait combien de paramètres il est censé obtenir. Cela provient du comptage des paramètres nommés dans config/routes. Il acceptera soit un hachage soit une liste d'arguments. Si vous lui donnez un hachage, les clés doivent correspondre aux noms des paramètres d'URL. Si vous lui donnez une liste d'arguments, il ne fera que les faire correspondre par position - le premier argument avec le premier paramètre nommé.

Ensuite, il appellera to_param on chaque paramètre individuellement avant de les joindre tous ensemble ( voir le code ici, branche 4. ).

Si vous passez un objet alors qu'il attend 2 paramètres ou plus, il ne pourra même pas appeler to_param sur l'objet. C'est là que vous obtenez des erreurs sans trace de pile qui disent quelque chose comme
No route matches {:controller=>"posts", :action=>"show", :id=>#<Post ...>}

Travailler avec 1 paramètre nommé

Si vous n'avez qu'un seul paramètre nommé, les choses sont assez simples. Si vous devez rechercher vos messages par nom au lieu de id, vous pouvez simplement redéfinir to_param

class Post < ActiveRecord::Base
  ...
  def to_param
    name
  end
end

Travailler avec plusieurs paramètres nommés

Mais si l'URL contient plusieurs paramètres nommés, redéfinissez to_param ne suffit pas. Disons que vous avez essayé ceci:

# app/models/post.rb
class Post < ActiveRecord::Base
  ...
  def to_param
    {name: name, title: title}
  end
end

# app/views/posts/index.html.erb
<%= post_path(post) %>

Dans ce cas, vous obtiendrez une erreur de routage car vous ne passez pas suffisamment d'arguments à post_path (voir ci-dessus). Pour contourner ce problème, j'appelle simplement to_param explicitement:

 # app/views/posts/index.html.erb
 <%= post_path(post.to_param) %>

C'est un peu moins lisse que la plupart Rails magie de routage, mais fonctionne parfaitement bien. Si vous changez plus tard la façon dont vous recherchez des messages, tout ce que vous avez à faire est de redéfinir to_param. Pas besoin à vous soucier de tous les endroits que vous avez appelés post_path

Sous la capuche

Le code pertinent à regarder est actionpack/lib/action_dispatch/routing

14
declan

Vous pouvez aussi l'appeler comme ça

hello_path(@post.name, @post.title)

J'espère que ça aide.

6
James

Les autres réponses (au moment d'écrire ces lignes) sont très bien, mais votre réponse à la réponse de GregT montre un manque de compréhension de Rails, ce qui est bien - nous avons tous été là.

Plus précisément, trois des principes clés de Rails: convention sur la configuration, architecture modèle-vue-contrôleur (MVC) et RESTE . Ce sont des trucs au début de chaque début Rails livre. Les débutants pensent souvent qu'ils peuvent simplement passer au premier chapitre avec du code, mais Rails diffère de beaucoup d'autres sujets) en ce que les premiers chapitres expliquent des concepts importants et ne sont pas seulement des remplisseurs de chapitre d'introduction. Parce que Rails n'est pas du "code", c'est un "framework de code".

"Convention sur configuration" signifie que si vous suivez certaines conventions, vous bénéficiez de comportements intégrés dans Rails. Le routage est l'un de ces domaines, sinon le plus grand, où la convention profite au développeur bien qu'elle soit entièrement configurable.

Les chemins suivant un format de routage spécifique sont analysés dans le contrôleur, l'action et éventuellement un identifiant, un format et des paramètres supplémentaires. Par défaut et au minimum, un chemin Rails (et aussi Sinatra) prend le format et l'ordre suivants:

/controller_name/action_name

C'est un peu plus compliqué que ça, avec plus d'options, et ça ressemble plus à ça en réalité:

/controller_name/action_name/(id)(.format)(?param=value)(&...)

... mais c'est plus de détails que nécessaire pour cette réponse.

Le contrôleur est le C dans MVC, ou la classe qui gère la demande. L'action est l'une des sept actions RESTful (index, show, new, create, edit, update et destroy) dans ce contrôleur. Toutes les actions ne nécessitent pas un identifiant (index, new et create) et toutes ne sont pas des requêtes get (requêtes qui génèrent une vue, par exemple destroy, create et update n'ont pas de vues).

En mettant tout cela ensemble, nous voyons cet exemple:

/articles/edit/1

... acheminera la demande vers l'action "modifier" dans le contrôleur ArticlesController en passant l'ID 1. On s'attend à ce que le contrôleur fasse un peu de ménage, comme l'authentification et l'autorisation, puis récupère le modèle d'article ( M CV) avec l'ID 1 et passez-le à la vue "edit" (MC V ).

Il est préférable, en particulier pour les nouveaux développeurs Rails, de respecter ces conventions et peut-être d'ajouter quelques actions supplémentaires au-delà de celles fournies par REST.

Vous pouvez sortir de cette convention en configurant dans votre fichier routes.rb un schéma de routage alternatif, ne suivant pas REST, etc., mais vous serez comme un saumon nageant en amont - c'est beaucoup plus difficile que de suivre le flux. Si vous suivez cette voie (jeu de mots), vous ferez beaucoup de travail supplémentaire pour vous-même, réinventerez probablement quelque peu la roue et perdrez les avantages fournis par le cadre Rails. Si vous vous cette situation pour une raison quelconque, peut-être Rails n'est pas le bon outil pour votre travail.

5
IAmNaN