rails cms camaleon ruby-on-rails ruby content-management-system erb

ruby on rails - cms - definido? método en Ruby and Rails



cms rails 5 (4)

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

local_assigns[:perex]

Esto está documentado en la API de Rails junto con la explicación que se defined? no se puede usar debido a una restricción de implementación.

Tengo un sistema de plantillas bastante antiguo escrito encima de ERB. Se basa en plantillas ERB almacenadas en la base de datos. Esos son leídos y renderizados. Cuando quiero pasar datos de una plantilla a otra utilizo el parámetro: locals al método de renderización de rieles. Para establecer las variables predeterminadas de esas variables en algunas plantillas, ¿utilizo el definido? 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 (a veces, Perex no está definido) y, a veces, no (Perex se define y establece en cero). Esto sucede sin cambiar nada más.

Tengo dos preguntas: ¿hay alguna otra forma mejor que usar el definido? que no es confiable (fue confiable durante varios años en Rails 1.6 superior)? Tal forma no debería resultar en que vuelva a escribir todas las plantillas. He estado revisando los documentos de Ruby y no he podido encontrar nada sobre los definidos. método. ¿Fue obsoleto 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 de menos funcionaría, pero a veces no. Lo extraño es que incluso si se ejecutara la segunda línea, Perex stil se mantendría nulo en el resto del mundo. ¿Eliminar definido? resuelto eso.


Por la respuesta de mislav, fui a buscar esa documentación en la API de Rails, y la encontré en Class ActionView :: Base (bajo el encabezado "Pasar variables locales a subpáginas"). Sin embargo, valió la pena la búsqueda, ya que apenas decía nada más que mislav. Excepto que recomienda este patrón:

if local_assigns.has_key? :perex


Primero: en realidad, defined? es un operador .

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

perex ||= true

Eso se asignará verdadero a perex si está indefinido o nil . No es exactamente lo que hace tu ejemplo, ya que el tuyo no evalúa la asignación cuando el valor es nil , pero si confías en eso, entonces, en mi opinión, sin verlo, no estás escribiendo un código claro.

Editar : Como señaló Honza, la afirmación anterior reemplazará el valor de " perex cuando sea false . Luego propongo lo siguiente para reescribir el número mínimo de líneas:

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


Tomando en consideración la respuesta original de mislav y la elaboración de KenB , creo que el siguiente es el mejor enfoque absoluto (aunque estoy abierto a la opinión). Utiliza el método Ruby''s Hash # fetch para recurrir a 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 a veces querrá permitir valores false . Por ejemplo, el siguiente código nunca permitirá que se pase un valor false :

perex = local_assigns[:perex] || true