Pregunta

Tengo un sistema de plantillas bastante antiguo escrito sobre ERB. Se basa en plantillas ERB almacenadas en la base de datos. Esos son leídos y prestados. Cuando quiero pasar datos de una plantilla a otra, uso el parámetro: locals para el método de renderizado de Rails. Para configurar las variables predeterminadas de esas variables en algunas plantillas, ¿uso las definidas? método que simplemente me dice si la variable local ha sido definida y si no la inicializo con un valor predeterminado como este:

unless defined?(perex)
  perex = true
end

Estoy actualizando la aplicación a los últimos Rails y veo un comportamiento extraño. Básicamente, esto a veces funciona (algunas veces perex no está definido) y otras veces no (perex se define y se establece en nulo). Esto sucede sin que nada cambie.

Tengo dos preguntas: ¿Hay alguna otra manera mejor que usar definido? ¿Qué está demostrando ser poco fiable (fue confiable durante varios años en los rieles superiores 1.6)? Tal manera no debería resultar en que reescriba todas las plantillas. He estado revisando los documentos de Ruby y no pude encontrar nada sobre lo definido. método. ¿Estaba en desuso o simplemente estoy ciego?

Editar: El problema real fue causado por lo que parece ser un error de Ruby / eRB. A veces la declaración a menos funcionaría, pero a veces no. Lo extraño es que, incluso si la segunda línea se ejecutó perex , todavía se mantuvo en el resto del mundo. Eliminando definido? Resuelto eso.

¿Fue útil?

Solución

Primero: en realidad, ¿definido? es un operador .

Segundo: si entiendo tu pregunta correctamente, la forma de hacerlo es con este lenguaje Ruby:

perex ||= true

Se asignará true a perex si no está definido o nil . No es exactamente lo que hace su ejemplo, ya que el suyo no evalúa la asignación cuando el valor es nil , pero si confía en eso, entonces, en mi opinión, sin verlo, no está escribiendo código claro.

Editar : como señaló Honza, la declaración anterior reemplazará el valor de perex cuando sea false . Luego propongo lo siguiente para volver a escribir el número mínimo de líneas:

perex ||= perex.nil?  # Assign true only when perex is undefined or nil

Otros consejos

La forma más segura de probar si se define un local en una plantilla de Rails es:

local_assigns[:perex]

Esto se documenta en la API de Rails junto con la explicación que define? no se puede usar debido a una restricción de implementación.

Por la respuesta de mislav, busqué esa documentación en la API de Rails y la encontré en Class ActionView :: Base (bajo el encabezado " Pasando variables locales a sub-plantillas "). Sin embargo, no valía la pena buscarlo, ya que apenas decía nada más que mislav. Salvo que recomienda este patrón:

if local_assigns.has_key? :perex

Teniendo en cuenta la respuesta original de mislav y elaboración de KenB , creo que el siguiente es el mejor enfoque absoluto (aunque Estoy abierto a la opinión). Utiliza el Hash # fetch de Ruby método para retroceder en un valor alternativo si la clave no existe en el hash original.

perex = local_assigns.fetch(:perex, true)

Esto es incluso mejor que el método || = que la mayoría de los usuarios sugerirán, ya que algunas veces querrá permitir valores de false . Por ejemplo, el siguiente código nunca permitirá que se pase un valor false :

perex = local_assigns[:perex] || true
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top