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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:08:34  来源:igfitidea点击:

optional local variables in rails partial templates: how do I get out of the (defined? foo) mess?

ruby-on-railspartials

提问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错误。这将允许您使用/不使用局部变量调用部分。