Ruby-on-rails rails 部分模板中的可选局部变量:我如何摆脱(定义?foo)的混乱?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2060561/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
optional local variables in rails partial templates: how do I get out of the (defined? foo) mess?
提问by brahn
I've been a bad kid and used the following syntax in my partial templates to set default values for local variables if a value wasn't explicitly defined in the :locals hash when rendering the partial --
我一直是个坏孩子,如果在渲染部分时未在 :locals 哈希中明确定义值,则在我的部分模板中使用以下语法为局部变量设置默认值-
<% foo = default_value unless (defined? foo) %>
This seemed to work fine until recently, when (for no reason I could discern) non-passed variables started behaving as if they had been defined to nil (rather than undefined).
直到最近,这似乎工作正常,当(无缘无故地辨别)未传递的变量开始表现得好像它们已被定义为 nil(而不是未定义)一样。
As has been pointed by various helpful people on SO, http://api.rubyonrails.org/classes/ActionView/Base.htmlsays notto use
正如各种有帮助的人所指出的那样,http: //api.rubyonrails.org/classes/ActionView/Base.html说不要使用
defined? foo
and instead to use
而是使用
local_assigns.has_key? :foo
I'm trying to amend my ways, but that means changing a lot of templates.
我正在尝试修改我的方法,但这意味着要更改很多模板。
Can/should I just charge ahead and make this change in all the templates? Is there any trickiness I need to watch for? How diligently do I need to test each one?
我可以/应该提前收费并在所有模板中进行此更改吗?有什么需要注意的地方吗?我需要多努力地测试每一个?
回答by jonnii
I do this:
我这样做:
<% some_local = default_value if local_assigns[:some_local].nil? %>
回答by Pablo Cantero
Since local_assignsis a hash, you could also use fetchwith the optional default_value.
由于local_assigns是散列,您还可以将fetch与可选的default_value.
local_assigns.fetch :foo, default_value
This will return default_valueif foowasn't set.
default_value如果foo未设置,这将返回。
WARNING:
警告:
Be careful with local_assigns.fetch :foo, default_valuewhen default_valueis a method, as it will be called anyway in order to pass its result to fetch.
小心local_assigns.fetch :foo, default_valuewhendefault_value是一个方法,因为它无论如何都会被调用以将其结果传递给fetch.
If your default_valueis a method, you can wrap it in a block: local_assigns.fetch(:foo) { default_value }to prevent its call when it's not needed.
如果您default_value是一个方法,您可以将它包装在一个块中:local_assigns.fetch(:foo) { default_value }以防止在不需要时调用它。
回答by hgmnz
How about
怎么样
<% foo ||= default_value %>
This says "use fooif it is not nil or true. Otherwise assign default_valueto foo"
这表示“foo如果它不是 nil 或 true,则使用。否则分配default_value给 foo”
回答by gamov
I think this should be repeated here (from http://api.rubyonrails.org/classes/ActionView/Base.html):
我认为这应该在这里重复(来自http://api.rubyonrails.org/classes/ActionView/Base.html):
If you need to find out whether a certain local variable has been assigned a value in a particular render call, you need to use the following pattern:
如果您需要找出某个局部变量是否已在特定渲染调用中赋值,则需要使用以下模式:
<% if local_assigns.has_key? :headline %>
Headline: <%= headline %>
<% end %>
Testing using defined? headline will not work. This is an implementation restriction.
测试使用定义?标题行不通。这是一个实现限制。
回答by Moises Portillo
In my case, I use:
就我而言,我使用:
<% variable ||= "" %>
in my partial.
I don't have idea if that is good but for my is OK
在我的部分。
我不知道这是否好,但对我来说还可以
回答by microspino
I know it's an old thread but here's my small contribution: i would use local_assigns[:foo].presencein a conditionalinside the partial.
Then i set fooonly when needed in the render call:
我知道这是一个旧线程,但这是我的小贡献:我会local_assigns[:foo].presence在部分内的条件中使用。然后我foo只在渲染调用中需要时设置:
<%= render 'path/to/my_partial', always_present_local_var: "bar", foo: "baz" %>
Have a look at te official Rails guide here. Valid from RoR 3.1.0.
在这里查看官方 Rails 指南。从 RoR 3.1.0 开始有效。
回答by sethcall
This is a derivative of Pablo's answer. This allows me to set a default ('full'), and in the end, 'mode' is set in both local_assigns and an actual local variable.
这是巴勃罗答案的衍生物。这允许我设置默认值('full'),最后,'mode' 在 local_assigns 和实际局部变量中设置。
haml/slim:
哈姆勒/苗条:
- mode ||= local_assigns[:mode] = local_assigns.fetch(:mode, 'full')
erb:
erb:
<% mode ||= local_assigns[:mode] = local_assigns.fetch(:mode, 'full') %>
回答by Daniel OCallaghan
I think a better option that allows for multiple default 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] %>
回答by muirbot
More intuitive and compact:
更直观和紧凑:
<% some_local = default_value unless local_assigns[:some_local] %>
<% some_local = default_value unless local_assigns[:some_local] %>
回答by Haris Krajina
If you do not want to pass local variable to partial each time you call it you do this:
如果您不想每次调用局部变量时都将局部变量传递给它,请执行以下操作:
<% local_param = defined?(local_param) ? local_param : nil %>
This way you avoid undefined variableerror. This will allow you to call your partial with/without local variables.
这样你就可以避免undefined variable错误。这将允许您使用/不使用局部变量调用部分。

