Eu sou um garoto mau e usei a seguinte sintaxe nos meus modelos parciais para definir valores padrão para variáveis locais se um valor não fosse explicitamente definido no: locals hash ao renderizar o parcial -
<% foo = default_value unless (defined? foo) %>
Isso pareceu funcionar bem até recentemente, quando (por nenhuma razão que eu pudesse discernir) variáveis não passadas começaram a se comportar como se tivessem sido definidas como nulas (em vez de indefinidas).
Como foi apontado por várias pessoas úteis no SO, http://api.rubyonrails.org/classes/ActionView/Base.html diz para não usar
defined? foo
e em vez de usar
local_assigns.has_key? :foo
Estou tentando alterar meus caminhos, mas isso significa alterar muitos modelos.
Posso / devo apenas cobrar antecipadamente e fazer essa alteração em todos os modelos? Existe algum truque que eu preciso prestar atenção? Com que diligência eu preciso testar cada um?
fonte
local_assigns.fetch
lida perfeitamente com chaves pares com valor nulo. Ele retorna um padrão apenas se a chave não estiver definida.Como
local_assigns
é um hash, você também pode usar a busca com o opcionaldefault_value
.Isso retornará
default_value
sefoo
não estiver definido.AVISO:
Tenha cuidado com
local_assigns.fetch :foo, default_value
quandodefault_value
é um método, pois ele será chamado assim mesmo para passar seu resultado parafetch
.Se você
default_value
é um método, pode agrupá-lo em um bloco:local_assigns.fetch(:foo) { default_value }
para impedir sua chamada quando não for necessário.fonte
nil
valores são preservados aqui. Se o hash contiver:foo
mapeado paranil
,fetch
ele retornaránil
. Ou seja, pelo menos na minha v1.9.3. Não me lembro como 1.8 se comportou.local_assigns[:foo] || default_value
, pois , quando foo retorna um valor falso, o valordefault_value
será usado. Geralmente, é um problema para memorização.@some_value ||= expensive_method
Se o método retornar um valor falso, ele sempre será executado.foo ||= local_assigns[:foo] = local_assigns.fetch(:foo, default_value)
foo = local_assigns.fetch :foo, true
E se
Isso diz "use
foo
se não for nulo ou verdadeiro. Caso contrário, atribuadefault_value
a foo"fonte
foo
for um booleano. Pode ter legitimamente o valor defalse
, e ser substituído pordefault_value
acidentalmente.Eu acho que isso deve ser repetido aqui (em http://api.rubyonrails.org/classes/ActionView/Base.html ):
Se você precisar descobrir se uma determinada variável local recebeu um valor em uma determinada chamada de renderização, use o seguinte padrão:
Teste usando definido? título não funcionará. Esta é uma restrição de implementação.
fonte
No meu caso, eu uso:
no meu parcial.
Eu não tenho idéia se isso é bom, mas para o meu é OK
fonte
nil
como local na chamada parcial também.variable
for um booleano e você precisar configurá-lo parafalse
. Ele usará o valor padrão em vez de usá-lofalse
. USE POR SUA CONTA E RISCO.Eu sei que é um thread antigo, mas aqui está minha pequena contribuição: eu usaria
local_assigns[:foo].presence
em um condicional dentro do parcial. Em seguida, definofoo
apenas quando necessário na chamada de renderização:Dê uma olhada no guia oficial do Rails aqui . Válido no RoR 3.1.0.
fonte
local_assigns[:foo]
elocal_assigns[:foo].presence
. Qualquer um retornaránil
se a chave não existir no hash e o valor se existir.Eu acho que uma opção melhor que permite várias variáveis padrão:
fonte
Este é um derivado da resposta de Pablo. Isso permite definir um padrão ('cheio') e, no final, 'mode' é definido em local_assigns e em uma variável local real.
haml / slim:
erb:
fonte
Mais intuitivo e compacto:
<% some_local = default_value unless local_assigns[:some_local] %>
fonte
:locals => {:some_local => false}
Se você não deseja passar a variável local para parcial toda vez que a chama, faça o seguinte:
Dessa forma, você evita
undefined variable
erros. Isso permitirá que você chame seu parcial com / sem variáveis locais.fonte
Ruby 2.5
Erb
É possível, mas você deve declarar seus valores padrão no escopo.
VARIÁVEL a palavra para substituição.
fonte
Um ajudante pode ser criado para ficar assim:
Implementado como:
Veja meu blog para obter detalhes sobre como e por quê.
Observe que esta solução permite que você passe nulo ou falso como o valor sem que seja substituído.
fonte