2010-06-24 15 views
25

Tengo un parcial, _flash.html.hamlmensajes flash en Parciales (carriles 3)

- flash.each do |type, value| 
    .flash{ :class => type.to_s } 
    = value 

que estoy representación de una vista usando

=render :partial => "flash"

Qué se queja de que el hash flash es nil/indefinido Sin embargo, cuando hago esto:

=render :partial => "flash", :locals => {:flash => flash}

Funciona.

¿Por qué el parcial no tiene acceso al mensaje flash?

Respuesta

24

En versiones anteriores de Rails (Rails 2), la variable local predeterminada buscaría una variable de instancia con el mismo nombre que el parcial en el elemento primario.

Dado su ejemplo, ya que el parcial se llama _flash pasaría automáticamente la variable de instancia flash como local al parcial. Por lo tanto, tendrías acceso a ella. Este comportamiento fue obsoleto en 2.3 y se ha eliminado en Rails 3.0.

Esto significa que siempre debe pasar explícitamente todas las variables de instancia como locals, incluso flash, tal como lo escribió en su último ejemplo.

<%= render :partial => "flash", :locals => {:flash => flash} %>

Esto no tiene nada que ver con flash por decir, flash es una variable de instancia como cualquier otro.

+2

Pero 'flash' no es una variable de instancia en la vista principal, es un método en' ActionView :: Base', que es esencialmente lo mismo que ser un método auxiliar. Entonces, ¿por qué no 'flash' en la llamada parcial el mismo método? – John

+8

Es porque el sombreado del espacio de nombres. El parcial se denomina flash, por lo que reserva el nombre de la variable flash dentro del parcial para delegar en flash ivar en la plantilla principal, independientemente de si el flash existe o no. Como respondió @tothemario, nombrarlo de otra forma detendrá el sombreado del espacio de nombres. – Cluster

+0

@Cluster, creo que me has dejado sin palabras. A veces me pregunto si Rails "majic" no es demasiado mágico por su propio bien. – guiniveretoo

22

Como su parcial se llama "_flash", debe tener: el objeto local para especificar la variable flash dentro del parcial.

cambiar su nombre parcial y usted será capaz de utilizar el flash en el interior, por ejemplo:

= render "show_flash_names" 
+1

Utilicé = render 'layouts/flash_messages'. Me gusta su solución mejor que pasar explícitamente a los locales. (: locals => {: flash => flash} es tan verboso - yuck) –

+2

+1 en esto: simplemente no lo nombre "flash" y puede acceder al objeto flash Rails como era de esperar. –

+0

¡Esta es la respuesta! – brad

4

Esto también lograr el resultado deseado:

<%= render partial: "flash", object: flash %>

está siendo el objeto flash pasó al admin/shared/flash parcial como flash, ya que el parcial se llama flash. Tendrás acceso al objeto flash desde el parcial como lo esperarías en cualquier vista normal.

5

Cada parcial se procesa en un contexto que contiene una variable local implícita cuyo nombre es el del parcial (excluyendo el guión bajo inicial). Por lo tanto, _flash.html.haml parcial tendrá always tiene un flash local que sombrea ActionView::Base#flash. Si usted no pasa un argumento a la parcial (ya sea a través :locals => {:flash => flash} o :object => flash, el valor de lo local es simplemente nil.

Como se ha sugerido, puede cambiar el nombre del parcial para evitar el conflicto de nombres, o utilizar la más prolija llama al render.

Esto es un error molesto de Rails, en mi opinión, y I'd like to see it changed.

+0

Esta es la respuesta más completa, proporcionando la causa y posibles soluciones. También aprecio sus esfuerzos para eliminar la "sorpresa" de esta "característica". –

Cuestiones relacionadas