在rails部分模板中可选的局部variables:我如何摆脱(定义的?foo)混乱?
我一直是个不好的孩子,在局部模板中使用下面的语法来为局部variables设置默认值,如果在渲染局部variables的时候,
<% foo = default_value unless (defined? foo) %>
这似乎工作正常,直到最近,当(无缘无故我能辨别)非传递variables开始performance,如果他们已被定义为零(而不是未定义)。
正如在SO上各种有帮助的人所指出的, http : //api.rubyonrails.org/classes/ActionView/Base.html表示不要使用
defined? foo
而是使用
local_assigns.has_key? :foo
我试图修改我的方法,但是这意味着改变了很多模板。
可以/应该提前充电,并在所有模板中进行此更改? 有什么需要注意的技巧吗? 我需要多努力testing每一个?
我这样做:
<% some_local = default_value if local_assigns[:some_local].nil? %>
由于local_assigns
是一个散列,你也可以使用可选的default_value
获取 。
local_assigns.fetch :foo, default_value
如果没有设置foo
,这将返回default_value
。
警告:
当default_value
是一个方法时,要小心local_assigns.fetch :foo, default_value
,因为它将被调用,以便将其结果传递给fetch
。
如果您的default_value
是一个方法,您可以将其封装在一个块中: local_assigns.fetch(:foo) { default_value }
以防止在不需要时调用它。
怎么样
<% foo ||= default_value %>
这说“使用foo
如果它不是零或真实的,否则分配给foo的default_value
”
我想这应该在这里重复(从http://api.rubyonrails.org/classes/ActionView/Base.html ):
如果您需要查明某个局部variables是否在特定的渲染调用中被赋值,则需要使用以下模式:
<% if local_assigns.has_key? :headline %> Headline: <%= headline %> <% end %>
testing使用定义? 标题将无法正常工作。 这是一个实施限制。
我知道这是一个古老的线程,但这是我的小小贡献:我将在部分条件内使用local_assigns[:foo].presence
。 然后我只在需要渲染调用时设置foo
:
<%= render 'path/to/my_partial', always_present_local_var: "bar", foo: "baz" %>
看看这里的官方Rails指南 。 从RoR 3.1.0起有效。
我认为更好的select,允许多个默认variables:
<% 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] %>
这是巴勃罗答案的衍生物。 这允许我设置一个默认('full'),最后在local_assigns和一个实际的局部variables中设置'mode'。
HAML /苗条:
- mode ||= local_assigns[:mode] = local_assigns.fetch(:mode, 'full')
ERB:
<% mode ||= local_assigns[:mode] = local_assigns.fetch(:mode, 'full') %>
在我的情况下,我使用:
<% variable ||= "" %>
在我的部分。
我不知道,如果这是好的,但我的确定
更直观,更紧凑:
<% some_local = default_value unless local_assigns[:some_local] %>
如果您不想每次调用局部variables时都使用局部variables,则可以这样做:
<% local_param = defined?(local_param) ? local_param : nil %>
这样可以避免undefined variable
错误。 这将允许你使用/不使用局部variables来调用你的局部variables。
可以创build一个助手看起来像这样:
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
查看我的博客 ,了解有关如何以及为什么
请注意,此解决scheme确实允许您传递nil或false作为值而不会被覆盖。