Я был плохим парнем и использовал следующий синтаксис в моих частичных шаблонах, чтобы установить значения по умолчанию для локальных переменных, если значение не было явно определено в хеше: locals при рендеринге частичного -
<% foo = default_value unless (defined? foo) %>
Казалось, это работало нормально до недавнего времени, когда (без какой-либо причины) непропущенные переменные начали вести себя так, как если бы они были определены как nil (а не как undefined).
Как указывалось различными полезными людьми на SO, http://api.rubyonrails.org/classes/ActionView/Base.html говорит, что не следует использовать
defined? foo
и вместо того, чтобы использовать
local_assigns.has_key? :foo
Я пытаюсь изменить свои способы, но это означает изменение большого количества шаблонов.
Можно / нужно просто зарядить заранее и внести это изменение во все шаблоны? Есть ли какая-то хитрость, за которой мне нужно следить? Насколько усердно мне нужно проверять каждого?
источник
local_assigns.fetch
отлично обрабатывает даже ключи с нулевым значением. Он возвращает значение по умолчанию, только если ключ не установлен вообще.Поскольку
local_assigns
это хеш, вы также можете использовать fetch с опциональнымdefault_value
.Это вернется,
default_value
еслиfoo
не было установлено.ПРЕДУПРЕЖДЕНИЕ:
Будьте осторожны с методом
local_assigns.fetch :foo, default_value
whendefault_value
, так как он все равно будет вызван, чтобы передать его результатfetch
.Если ваш
default_value
метод, вы можете заключить его в блок:local_assigns.fetch(:foo) { default_value }
для предотвращения его вызова, когда он не нужен.источник
nil
здесь сохраняются значения. Если хеш содержит:foo
сопоставленныйnil
, тоfetch
он вернетсяnil
. То есть по крайней мере на моем v1.9.3. Я не помню, как вела себя 1.8.local_assigns[:foo] || default_value
, когда foo возвращает ложное значение,default_value
вместо него будет использоваться. Обычно для Мемоизации возникает проблема,@some_value ||= expensive_method
если метод возвращает ложное значение, оно всегда будет выполняться.foo ||= local_assigns[:foo] = local_assigns.fetch(:foo, default_value)
foo = local_assigns.fetch :foo, true
Как насчет
Это говорит "используйте,
foo
если это не ноль или истина. В противном случае назначьтеdefault_value
foo"источник
foo
это логическое значение. Он может по праву иметь значениеfalse
и может бытьdefault_value
случайно изменен .Я думаю, что это должно быть повторено здесь (с http://api.rubyonrails.org/classes/ActionView/Base.html ):
Если вам нужно выяснить, было ли определенной локальной переменной присвоено значение в конкретном вызове рендеринга, вам нужно использовать следующий шаблон:
Тестирование с использованием определенных? заголовок не будет работать. Это ограничение реализации.
источник
В моем случае я использую:
в моем частичном.
Я понятия не имею, если это хорошо, но для меня это нормально
источник
nil
как локальный в частичном вызове.variable
это логическое значение, и вам нужно установить егоfalse
. Он будет использовать значение по умолчанию вместо использованияfalse
значения. ИСПОЛЬЗУЙТЕ НА СВОЙ РИСК.Я знаю, что это старая ветка, но вот мой маленький вклад: я бы использовал
local_assigns[:foo].presence
в условной части в частичной. Затем я устанавливаюfoo
только при необходимости в вызове рендеринга:Взгляните на официальный путеводитель по Rails здесь . Действительно с RoR 3.1.0.
источник
local_assigns[:foo]
иlocal_assigns[:foo].presence
. Любой из них вернется,nil
если ключ не существует в хэше, и значение, если оно существует.Я думаю, что лучший вариант, который учитывает несколько переменных по умолчанию:
источник
Это производная от ответа Пабло. Это позволяет мне установить значение по умолчанию ('full'), и, в конце, 'mode' устанавливается как в local_assigns, так и в реальной локальной переменной.
Haml / тонкий:
Еврорадио:
источник
Более интуитивно понятный и компактный:
<% some_local = default_value unless local_assigns[:some_local] %>
источник
:locals => {:some_local => false}
Если вы не хотите передавать локальную переменную в частичную каждый раз, когда вы вызываете ее, вы делаете это:
Таким образом вы избежите
undefined variable
ошибки. Это позволит вам вызвать ваш частичный с / без локальных переменных.источник
Ruby 2.5
эрб
Это возможно, но вы должны объявить значения по умолчанию в области видимости.
ПЕРЕМЕННОЕ слово для замены.
источник
Помощник может быть создан, чтобы выглядеть так:
Реализовано так:
Смотрите мой блог для деталей о том, как и почему.
Обратите внимание, что это решение позволяет вам передавать nil или false в качестве значения без переопределения.
источник