Rails: confus sur la syntaxe pour faire passer les sections locales aux partiels

Comprendre les Rails “magiques” en ce qui concerne le rendu des partiels (et la transmission des locaux).

Pourquoi ça marche:

 

Et ce travail:

  @warren, :flash => flash %> 

mais cela ne fonctionne pas :

  { :parent => @warren, :flash => flash } %> 

Mais cela fait:

 "rabbits/form", :locals => { :parent => @warren, :flash => flash } %> 

En outre, comment puis-je rechercher ces nuances pour ne pas avoir à déranger les gens sur SO?

La réponse courte est que la méthode de rendu examine le premier argument que vous avez entré. Si vous passez un hachage (qui comprend :partial => 'foo', :locals => {blah blah blah} ), tout cela passera vos arguments en tant que hachage et les parsingr en conséquence.

Si vous passez une chaîne en tant que votre premier argument, cela suppose que le premier argument est votre nom partiel et transmettra le rest en tant que vos locaux. Cependant, dans cet appel suivant, il affecte réellement :locals => your_locals_argument , qui dans ce cas est la totalité :locals => {locals hash} , au lieu de {locals hash} uniquement {locals hash} ; c’est-à-dire que vous vous retrouvez avec :locals => {:locals => {locals hash}} , plutôt que :locals => {locals hash} .

Donc, mon conseil est de toujours passer les valeurs de la même manière de manière explicite, et vous n’aurez aucun problème. Pour en savoir plus, je suis allé directement au code lui-même ( actionpack / lib / base.rb , méthode render() dans Rails 2; Rails 3 est différent). C’est un bon exercice.

De plus, ne vous inquiétez pas pour “déranger” les gens sur SO. C’est pourquoi ce site existe. J’ai même appris quelque chose à ce sujet.

si vous avez besoin de spécifier: les locaux, vous devez spécifier: partial ou: template

 <%= render :partial => "rabbits/form", :locals => {...} %> 

devrait marcher

Pour être honnête, je ne connais que ces cas d’utilisation, car je me suis tenu au courant des dernières années et j’ai lu les annonces indiquant qu’une nouvelle façon de procéder avait été ajoutée. Je fais souvent une erreur en moi-même, mais en général, cela se corrige facilement.

C’est l’une des parties de l’API Rails qui n’a pas été complètement pensée, si vous me le demandez. Il a simplement accumulé de plus en plus de sucre syntaxique au fil des ans, sans pour autant renier aucun des anciens comportements. La méthode de rendu a le diabète.

Pour le rendre encore pire, le rendu se comporte différemment dans le contrôleur et la vue. Je regarde également le contenu du premier argument pour voir s’il s’agit d’un fichier, d’un modèle, d’une action ou d’une partie. Si cela commence par une barre oblique, alors c’est un fichier ou quelque chose comme ça.

Je suis favorable à l’utilisation de la notation la plus courte possible. Parce que les notes courtes communiquent assez bien l’intention. En le lisant, il fait généralement ce que vous pensez. L’écrire n’est pas si simple.

Voici la source de la méthode de rendu de http://api.rubyonrails.org/classes/ActionView/Rendering.html#method-i-render :

 def render(options = {}, locals = {}, &block) case options # Here is your last case when Hash if block_given? _render_partial(options.merge(:partial => options.delete(:layout)), &block) elsif options.key?(:partial) _render_partial(options) else template = _determine_template(options) lookup_context.freeze_formats(template.formats, true) _render_template(template, options[:layout], options) end when :update update_page(&block) else # here the first three cases _render_partial(:partial => options, :locals => locals) end end 

J’espère que cette aide!