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

Ruby on rails rails部分模板中的可选局部变量:如何摆脱(定义的?foo)混乱?,ruby-on-rails,partials,Ruby On Rails,Partials,我是个坏孩子,在呈现部分时,如果没有在:locals散列中显式定义值,我在部分模板中使用以下语法为局部变量设置默认值-- 而是使用 local_assigns.has_key? :foo 我试图改变我的方式,但这意味着改变了很多模板 我是否可以/应该提前收费并在所有模板中进行此更改?有什么诡计需要我注意吗?我需要付出多大的努力来测试每一个呢?怎么样 <% foo ||= default_value %> 这表示“如果不是nil或true,则使用foo。否则将default\u

我是个坏孩子,在呈现部分时,如果没有在:locals散列中显式定义值,我在部分模板中使用以下语法为局部变量设置默认值--

而是使用

local_assigns.has_key? :foo
我试图改变我的方式,但这意味着改变了很多模板

我是否可以/应该提前收费并在所有模板中进行此更改?有什么诡计需要我注意吗?我需要付出多大的努力来测试每一个呢?

怎么样

<% foo ||= default_value %>

这表示“如果不是nil或true,则使用
foo
。否则将
default\u值指定给foo”

我执行以下操作:

<% some_local = default_value if local_assigns[:some_local].nil? %>

可以创建如下所示的帮助器:

somearg = opt(:somearg) { :defaultvalue }
实施方式如下:

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
请参阅,以获取有关如何以及为什么这样做的详细信息


请注意,此解决方案允许您将nil或false作为值传递,而无需覆盖它。

更直观、更紧凑:


我认为一个更好的选择是允许多个默认变量:

<% 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] %>
true,:include_js=>true)%>

我认为这应该在这里重复(从):

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

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

标题:

使用定义的测试?标题行不通。这是一个实现限制。

由于
本地\u分配
是一个散列,因此您也可以将其与可选的
默认值
一起使用

local\u assigns.fetch:foo,默认值
如果未设置
foo
,则将返回
default\u值

警告:

注意
local\u assigns.fetch:foo,当
default\u value
是一个方法时,默认值
,因为它无论如何都会被调用,以便将结果传递给
fetch


如果您的
default\u值
是一个方法,您可以将其包装在块中:
local\u assigns.fetch(:foo){default\u值}
以防止在不需要时调用它。

如果您不想在每次调用局部变量时将其传递给partial,请执行以下操作:

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


这样可以避免
未定义变量
错误。这将允许您调用带有/不带局部变量的偏微分。

这是Pablo答案的导数。这允许我设置一个默认值('full'),最后在局部变量和实际局部变量中设置'mode'

haml/slim:

- mode ||= local_assigns[:mode] = local_assigns.fetch(:mode, 'full')
雇员再培训局:


我知道这是一个旧线程,但这里是我的一个小贡献:我将使用
局部赋值[:foo]。在分部中的条件中存在。
然后,我仅在渲染调用中需要时设置
foo

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

看一看。从RoR 3.1.0开始生效。

在我的情况下,我使用:

<% variable ||= "" %>

在我看来
我不知道这是否好,但对于我的用户来说是OK的

Ruby 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 %>
...
#index.html.erb
...
...
#_some_content.html.erb
...
你看见我了吗?
...


我不确定这是否有效,因为除非通过局部变量散列传入,否则不会定义foo。这是有效的,但如果您有这样的默认值,可能是您应该使用帮助器的标志?这里没有魔法。关于这个主题的更多资源:我非常喜欢这个版本,因为它的语法非常紧凑。我想最大的缺点是,这意味着不能将nil或false作为本地值传递,因为默认情况下它会被覆盖。@brahn,这是一个很好的观点。事实上,如果
foo
是布尔值,则应该避免这种情况。它的值可能正确地为
false
,并意外地被
default\u值
覆盖。尽管我非常喜欢hgimenez建议(如上)的简洁语法,但这种方法的优点是非常清楚:发生了什么。(仍然有一个缺点,就是不允许您将nil作为本地值传递)您希望传递nil的用例是什么?哦,我脑子里没有具体的用例。只是想了解其中的全部含义。这提醒我接受这个答案:-)为了克服nil问题,我从OP的link()标题复制了代码:--has_key避免了nil/false的情况,并且可能可以缩短为一行,就像这里的答案一样。请检查Pablo的答案:
local_assignments。fetch
完美地处理了即使是具有nil值的键。只有在根本没有设置键的情况下,它才会返回默认值。我认为,如果使用
:locals=>{:some\u local=>false}
调用分部函数,则此操作将失败。值得明确指出的是:
nil
值保留在此处。如果哈希包含映射到
nil
:foo
,则
fetch
将返回
nil
。也就是说,至少在我的v1.9.3上是这样。我不记得1.8是怎么运行的,完全正确。它让我想起了
local_assigns[:foo]| | default_value
的问题,当foo返回一个falsy值时,将使用
default_value
。对于Memoization
@some_value | | |=昂贵的_方法
来说,这通常是一个问题。如果该方法返回错误的值,它将始终被执行。任何不理解这为什么是最佳答案的人都没有使用ruby足够长的时间。巴勃罗,好极了!优化如下,因此您只需在模板顶部调用一次,而不是每次使用变量时都使用“fetch guard”
foo | |=local_assigns[:foo]=local_assigns.fetch(:foo,默认值)
我想知道为什么它不起作用,我假设它也创建了变量,但我们仍然必须使用返回值:
foo=local_assigns.fetch:foo,true
或local_param=local_param,如果定义的话?(local_param)这实际上起作用
<%= render 'path/to/my_partial', always_present_local_var: "bar", foo: "baz" %>
<% variable ||= "" %>
# 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 %>
...