Comprendre Rails "magique" en ce qui concerne le rendu des partiels (et leur passer des locaux).
Pourquoi ça marche:
<%= render "rabbits/form" %>
Et ce travail:
<%= render "rabbits/form", :parent => @warren, :flash => flash %>
mais cela fonctionne pas:
<%= render "rabbits/form", :locals => { :parent => @warren, :flash => flash } %>
Mais cela:
<%= render :partial =>"rabbits/form", :locals => { :parent => @warren, :flash => flash } %>
De plus, comment puis-je rechercher ces nuances pour ne pas avoir à déranger les gens sur S.O.?
La réponse courte est que la méthode de rendu examine le premier argument que vous passez. Si vous passez un hachage (qui inclut :partial => 'foo', :locals => {blah blah blah}
), Il passera tous vos arguments en tant que hachage et les analysera en conséquence.
Si vous passez une chaîne comme premier argument, cela suppose que le premier argument est votre nom partiel et passera le reste en tant que vos sections locales. Cependant, lors de cet appel ultérieur, il affecte en fait :locals => your_locals_argument
, Qui dans ce cas est l'intégralité de :locals => {locals hash}
, Au lieu de simplement {locals hash}
; c'est-à-dire que vous vous retrouvez avec :locals => {:locals => {locals hash}}
, plutôt que :locals => {locals hash}
.
Donc, mon conseil est juste de toujours passer explicitement les valeurs de la même manière tout le temps, et vous n'aurez pas de problèmes. Pour en savoir plus, je suis allé directement au code lui-même (actionpack/lib/base.rb, render()
méthode dans Rails 2 ; Rails 3 est différent). C'est un bon exercice.
De plus, ne vous inquiétez pas de "déranger" les gens sur SO. C'est pourquoi ce site existe. J'ai même appris quelque chose de cela.
si vous devez spécifier: locaux, vous devez spécifier: partiel ou: modèle
<%= render :partial => "rabbits/form", :locals => {...} %>
devrait marcher
Pour être honnête, je ne connais que ces cas d'utilisation, car j'ai suivi Rails au cours des deux dernières années et j'ai lu les annonces qu'une nouvelle façon de le faire a été ajoutée. J'y fais souvent moi-même une erreur, mais en général c'est facile à corriger.
C'est l'une de ces parties de l'API Rails qui n'a pas été bien pensée, si vous me demandez. Elle a simplement accumulé de plus en plus de sucre syntaxique au fil des ans, sans déprécier aucune La méthode de rendu est diabétique.
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 partiel. Si cela commence par une barre oblique, c'est un fichier, ou quelque chose comme ça.
Je suis en faveur de l'utilisation de la notation la plus courte dans la mesure du possible. Parce que les courtes notations communiquent assez bien l'intention. En le lisant, il fait généralement ce que vous pensez qu'il fait. 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!