необязательные локальные переменные в частичных шаблонах rails: как мне выйти из (определенного? foo) беспорядка? - PullRequest
214 голосов
/ 14 января 2010

Я был плохим ребенком и использовал следующий синтаксис в моих частичных шаблонах, чтобы установить значения по умолчанию для локальных переменных, если значение не было явно определено в хеше: locals при рендеринге частичного -

<% foo = default_value unless (defined? foo) %>

Это, казалось, работало нормально до недавнего времени, когда (без причины я мог различить) непропущенные переменные начали вести себя так, как будто они были определены как ноль (а не как неопределенные).

Как указывалось различными полезными людьми на SO, http://api.rubyonrails.org/classes/ActionView/Base.html говорит не для использования

defined? foo

и вместо этого использовать

local_assigns.has_key? :foo

Я пытаюсь изменить свои способы, но это означает, что нужно изменить множество шаблонов.

Можно / нужно просто зарядить заранее и внести это изменение во все шаблоны? Есть ли какая-то хитрость, за которой мне нужно следить? Насколько усердно мне нужно проверять каждого?

Ответы [ 12 ]

308 голосов
/ 14 января 2010

Я делаю это:

<% some_local = default_value if local_assigns[:some_local].nil? %>
147 голосов
/ 27 июня 2013

Поскольку local_assigns является хэшем, вы также можете использовать fetch с необязательным default_value.

local_assigns.fetch :foo, default_value

Это вернет default_value, если foo не было установлено.

ВНИМАНИЕ:

Будьте осторожны с local_assigns.fetch :foo, default_value, когда default_value является методом, так как он будет вызван в любом случае для передачи его результата в fetch.

Если ваш default_value является методом, вы можете заключить его в блок: local_assigns.fetch(:foo) { default_value }, чтобы предотвратить его вызов, когда он не нужен.

82 голосов
/ 14 января 2010

Как насчет

<% foo ||= default_value %>

Это говорит "используйте foo, если оно не равно нулю или истине. В противном случае присвойте default_value foo"

10 голосов
/ 26 марта 2013

Я думаю, что это должно быть повторено здесь (от http://api.rubyonrails.org/classes/ActionView/Base.html):

Если вам нужно выяснить, было ли определенной локальной переменной присвоено значение в конкретном вызове рендеринга, вам нужно использовать следующий шаблон:

<% if local_assigns.has_key? :headline %>
  Headline: <%= headline %>
<% end %>

Тестирование с использованием определенных? заголовок не будет работать. Это ограничение реализации.

5 голосов
/ 29 мая 2015

В моем случае я использую:

<% variable ||= "" %>

в моем частичном.
Я понятия не имею, если это хорошо, но для меня это нормально

4 голосов
/ 29 августа 2014

Я знаю, что это старая ветка, но вот мой маленький вклад: я бы использовал local_assigns[:foo].presence в условном внутри партиала. Затем я устанавливаю foo только при необходимости в вызове рендеринга:

<%= render 'path/to/my_partial', always_present_local_var: "bar", foo: "baz" %>

Взгляните на официальное руководство по Rails здесь . Действительно с RoR 3.1.0.

1 голос
/ 13 августа 2014

Это производная от ответа Пабло. Это позволяет мне установить значение по умолчанию ('full'), и, в конце, 'mode' устанавливается как в local_assigns, так и в фактическую локальную переменную.

Haml / тонкий:

- mode ||= local_assigns[:mode] = local_assigns.fetch(:mode, 'full')

Еврорадио:

<% mode ||= local_assigns[:mode] = local_assigns.fetch(:mode, 'full') %>
1 голос
/ 13 марта 2012

Я думаю, что лучший вариант, который учитывает несколько переменных по умолчанию:

<% 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] %>
0 голосов
/ 12 августа 2018

Рубин 2,5

Эрба

Это возможно, но вы должны объявить значения по умолчанию в области.

ПЕРЕМЕННЫЕ слово для замены.

# 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 %>
...
0 голосов
/ 18 ноября 2013

Если вы не хотите передавать локальную переменную в частичное каждый раз, когда вы вызываете ее, вы делаете это:

<% local_param = defined?(local_param) ? local_param : nil %>

Таким образом вы избежите ошибки undefined variable. Это позволит вам вызывать ваше частичное с / без локальных переменных.

...