rails部分模板中的可选局部变量:如何摆脱(定义的?foo)混乱局面?

bra*_*ahn 221 ruby-on-rails partials

我是一个坏孩子,并在我的部分模板中使用以下语法来设置局部变量的默认值,如果在渲染部分时未在:locals哈希中显式定义值 -

<% foo = default_value unless (defined? foo) %>
Run Code Online (Sandbox Code Playgroud)

直到最近,这似乎工作正常(当时我无法辨别)未通过的变量开始表现得好像它们被定义为nil(而不是未定义).

正如SO上各种乐于助人的人所指出的,http://api.rubyonrails.org/classes/ActionView/Base.html表示使用

defined? foo
Run Code Online (Sandbox Code Playgroud)

而是使用

local_assigns.has_key? :foo
Run Code Online (Sandbox Code Playgroud)

我正在尝试修改我的方法,但这意味着要更改很多模板.

可以/我应该提前充电并在所有模板中进行此更改吗?我需要注意什么诡计?我需要多努力地测试每一个?

jon*_*nii 319

我这样做:

<% some_local = default_value if local_assigns[:some_local].nil? %>
Run Code Online (Sandbox Code Playgroud)

  • 请检查Pablo的答案:`local_assigns.fetch`可以完美处理具有nil值的偶数键.仅当键未设置**时才返回默认值. (5认同)
  • 为了解决这个问题,我正在复制OP链接中的代码(http://api.rubyonrails.org/classes/ActionView/Base.html)<%if local_assigns.has_key?:标题%>标题:<%=标题%> <%end%> - has_key避免了nil/false情况,可能会缩短为一行,就像这里的答案一样 (4认同)

Pab*_*ero 153

既然local_assigns是哈希,你也可以使用fetch和optional default_value.

local_assigns.fetch :foo, default_value
Run Code Online (Sandbox Code Playgroud)

default_value如果foo没有设置,这将返回.

警告:

小心local_assigns.fetch :foo, default_value何时default_value是一个方法,因为它将被调用以便将结果传递给它fetch.

如果你default_value是一个方法,你可以将它包装在一个块中:local_assigns.fetch(:foo) { default_value }以防止在不需要时调用它.

  • 这是**正确的**答案.干得好,巴勃罗^.^ (7认同)
  • 优化如下,因此您只需在模板顶部调用一次,而不是在每次使用变量时使用"fetch guard".`foo || = local_assigns [:foo] = local_assigns.fetch(:foo,default_value)` (2认同)

hgm*_*mnz 84

怎么样

<% foo ||= default_value %>
Run Code Online (Sandbox Code Playgroud)

这说" foo如果它不是零或真,则使用.否则分配default_value给foo"

  • 我非常喜欢这个版本,因为语法非常紧凑.我认为最大的缺点是它意味着你不能传递nil或false作为本地的值,因为它将被默认值覆盖. (35认同)
  • @brahn,这是一个好点.实际上,如果`foo`是布尔值,应该避免这种情况.它可能正确地具有"false"的值,并被意外地被"default_value"覆盖. (15认同)
  • 我不确定这是否有效,因为foo没有被定义,除非它通过locals hash传入. (2认同)
  • 这里没有魔力.有关此主题的更多资源:http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/fe4fbc48e19105cd/bf7f73380e285aff?lnk = gst&q = Or+equal (2认同)

gam*_*mov 10

我想这应该在这里重复一遍(来自http://api.rubyonrails.org/classes/ActionView/Base.html):

如果需要确定某个局部变量是否已在特定渲染调用中分配了值,则需要使用以下模式:

<% if local_assigns.has_key? :headline %>
  Headline: <%= headline %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

测试使用定义?标题不起作用.这是一个实施限制.


mic*_*ino 5

我知道这是一个旧线程,但这是我的小贡献:我会local_assigns[:foo].presence在部分内的条件中使用。然后我foo只在渲染调用中需要时设置:

<%= render 'path/to/my_partial', always_present_local_var: "bar", foo: "baz" %>
Run Code Online (Sandbox Code Playgroud)

这里查看官方 Rails 指南。从 RoR 3.1.0 开始有效。


Moi*_*llo 5

就我而言,我使用:

<% variable ||= "" %>
Run Code Online (Sandbox Code Playgroud)

在我的部分。
我不知道那是否好,但是对我来说还可以

  • 啊,往下读,如果 `variable` 是一个布尔值并且你需要将它设置为 `false`,这将失败。它将使用默认值而不是使用 `false` 值。使用风险自负。 (5认同)