variables locales opcionales en plantillas parciales de rails: ¿cómo salgo del (definido? foo) mess?
He sido un chico malo y he utilizado la siguiente sintaxis en mis plantillas parciales para establecer valores predeterminados para las variables locales si un valor no se definió explícitamente en el hash :locals al representar el parcial {
<% foo = default_value unless (defined? foo) %>
Esto parecía funcionar bien hasta hace poco, cuando (por ninguna razón pude discernir) las variables no pasadas comenzaron a comportarse como si hubieran sido definidas a cero (en lugar de indefinidas).
Como ha sido señalado por varias personas útiles en SO, http://api.rubyonrails.org/classes/ActionView/Base.html dice no usar
defined? foo
Y en su lugar usar
local_assigns.has_key? :foo
Estoy tratando de modificar mis métodos, pero eso significa cambiar muchas plantillas.
¿Puedo/debo simplemente cargar y hacer este cambio en todas las plantillas? ¿Hay algún problema debo tener cuidado? ¿Qué tan diligentemente necesito probar cada uno?
12 answers
Hago esto:
<% some_local = default_value if local_assigns[:some_local].nil? %>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-17 22:03:33
Dado que local_assigns
es un hash, también puedes usar fetch con el opcional default_value
.
local_assigns.fetch :foo, default_value
Esto devolverá default_value
si foo
no se ha establecido.
ADVERTENCIA:
Tenga cuidado con local_assigns.fetch :foo, default_value
cuando default_value
es un método, ya que se llamará de todos modos para pasar su resultado a fetch
.
Si su default_value
es un método, puede envolverlo en un bloque: local_assigns.fetch(:foo) { default_value }
para evitar su llamada cuando no es necesario.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-01 15:52:00
¿Qué tal
<% foo ||= default_value %>
Esto dice "use foo
si no es nil o verdadero. De lo contrario asignar default_value
a foo "
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-13 22:35:17
Creo que esto debería repetirse aquí (de http://api.rubyonrails.org/classes/ActionView/Base.html):
Si necesita averiguar si a cierta variable local se le ha asignado un valor en una llamada de renderizado en particular, debe usar el siguiente patrón:
<% if local_assigns.has_key? :headline %>
Headline: <%= headline %>
<% end %>
Testing using defined? el titular no funcionará. Esta es una restricción de implementación.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-09 06:31:18
Sé que es un hilo viejo pero aquí está mi pequeña contribución: usaría local_assigns[:foo].presence
en un condicional dentro del parcial.
Luego establezco foo
solo cuando es necesario en la llamada de renderizado:
<%= render 'path/to/my_partial', always_present_local_var: "bar", foo: "baz" %>
Echa un vistazo a la guía oficial de Rails aquí . Válido desde RoR 3.1.0.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-28 22:04:56
En mi caso, utilizo:
<% variable ||= "" %>
En mi parcial.
No tengo idea si eso es bueno, pero para mi está bien
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-28 22:50:59
Creo que una mejor opción que permite múltiples variables predeterminadas:
<% options = local_assigns.reverse_merge(:include_css => true, :include_js => true) %>
<%= include_stylesheets :national_header_css if options[:include_css] %>
<%= include_javascripts :national_header_js if options[:include_js] %>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-13 03:39:44
Esto es un derivado de la respuesta de Pablo. Esto me permite establecer un valor predeterminado ('full'), y al final,' mode ' se establece tanto en local_assigns como en una variable local real.
Haml / slim:
- mode ||= local_assigns[:mode] = local_assigns.fetch(:mode, 'full')
Erb:
<% mode ||= local_assigns[:mode] = local_assigns.fetch(:mode, 'full') %>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-13 15:59:03
Más intuitivo y compacto:
<% some_local = default_value unless local_assigns[:some_local] %>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-16 20:07:34
Si no desea pasar la variable local a partial cada vez que la llame, haga lo siguiente:
<% local_param = defined?(local_param) ? local_param : nil %>
De esta manera se evita el error undefined variable
. Esto le permitirá llamar a su parcial con / sin variables locales.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-04 19:32:14
Ruby 2.5
Erb
Es posible, pero debe declarar sus valores predeterminados en el ámbito.
VARIABLE la palabra para reemplazo.
# index.html.erb
...
<%= render 'some_content', VARIABLE: false %>
...
# _some_content.html.erb
...
<% VARIABLE = true if local_assigns[:VARIABLE].nil? %>
<% if VARIABLE %>
<h1>Do you see me?</h1>
<% end %>
...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-12 15:52:24
Se puede crear un ayudante para que se vea así:
somearg = opt(:somearg) { :defaultvalue }
Implementado como:
module OptHelper
def opt(name, &block)
was_assigned, value = eval(
"[ local_assigns.has_key?(:#{name}), local_assigns[:#{name}] ]",
block.binding)
if was_assigned
value
else
yield
end
end
end
Ver mi blog para detalles sobre cómo y por qué.
Tenga en cuenta que esta solución le permite pasar nil o false como el valor sin que se anule.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-30 02:16:29