Ruby迭代变量,除非它是零

时间:2022-04-30 14:31:05

I would like a clean way in .html.erb to loop through a variable ONLY if the variable is not nil.

如果变量不是nil,我想在.html.erb中以干净的方式循环遍历变量。

I would like the following to execute but not if @family is nil.

如果@family为nil,我希望执行以下操作。

<% @family.children.each.with_index(1) do |family_member, index| %>
    // HTML HERE
<% end %>

I am trying to avoid doing something like this

我试图避免做这样的事情

<% if @family %>
   <% @family.children.each.with_index(1) do |family_member, index| %>
       // HTML HERE
   <% end %>
<% end %>

And especially trying to avoid needing

特别是试图避免需要

<% if @family && @family.children %>
      <% @family.children.each.with_index(1) do |family_member, index| %>
          // HTML HERE
      <% end %>
<% end %>

Is there a better way to do this?

有一个更好的方法吗?

5 个解决方案

#1


5  

This solution can be misleading but Ruby's syntax allows you to do so:

这个解决方案可能会产生误导,但Ruby的语法允许您这样做:

<% @family.children.each.with_index(1) do |family_member, index| %>
    // HTML HERE
<% end unless @family.blank? %>
#      ^^^^^^^^^^^^^^^^^^^^^

I only use this solution for simple statements like testing the presence of an object (like in your case). I do not recommend this solution for a more complex logic because a third party would not know that the condition is at the end of the block.

我只将此解决方案用于简单的语句,例如测试对象的存在(就像你的情况一样)。我不推荐这种解决方案用于更复杂的逻辑,因为第三方不知道条件是在块的末尾。


Another one:

另一个:

<% (@family.try(:children) || []).each.with_index(1) do |family_member, index| %>

# mu-is-too-short's (brilliant) suggestion:
<% @family.try(:children).to_a.each.with_index(1) do |family_member, index| %>

If @family is nil, the try(:children) won't raise an error but will return nil, then nil || [] returns the empty array which "you can loop on it" (loop on it zero times actually).

如果@family为nil,则try(:children)不会引发错误,但会返回nil,然后是nil || []返回“你可以在它上面循环”的空数组(实际上循环为零)。

#2


5  

You could use a Null Object, something like:

您可以使用Null对象,例如:

class NullFamily
  def children
    []
  end
end

In your controller:

在你的控制器中:

@family = some_finder || NullFamily.new

Or you could pass a separate variable @children:

或者你可以传递一个单独的变量@children:

@family = some_finder
@children = @family.try(:children).to_a

And change your loop to:

并将您的循环更改为:

<% @children.each.with_index(1) do |family_member, index| %>
    // HTML HERE
<% end %>

#3


4  

How about this:

这个怎么样:

<% @family && @family.children.each.with_index(1) do |family_member, index| %>
    // HTML HERE
<% end %>

#4


1  

Maybe you can have this in your controller?

也许你可以在控制器中拥有它?

@family ||= []

#5


0  

You can use if @family.present? or the opposite as unless @family.blank?

您可以使用if @ family.present吗?或者相反,除非@ family.blank?

#1


5  

This solution can be misleading but Ruby's syntax allows you to do so:

这个解决方案可能会产生误导,但Ruby的语法允许您这样做:

<% @family.children.each.with_index(1) do |family_member, index| %>
    // HTML HERE
<% end unless @family.blank? %>
#      ^^^^^^^^^^^^^^^^^^^^^

I only use this solution for simple statements like testing the presence of an object (like in your case). I do not recommend this solution for a more complex logic because a third party would not know that the condition is at the end of the block.

我只将此解决方案用于简单的语句,例如测试对象的存在(就像你的情况一样)。我不推荐这种解决方案用于更复杂的逻辑,因为第三方不知道条件是在块的末尾。


Another one:

另一个:

<% (@family.try(:children) || []).each.with_index(1) do |family_member, index| %>

# mu-is-too-short's (brilliant) suggestion:
<% @family.try(:children).to_a.each.with_index(1) do |family_member, index| %>

If @family is nil, the try(:children) won't raise an error but will return nil, then nil || [] returns the empty array which "you can loop on it" (loop on it zero times actually).

如果@family为nil,则try(:children)不会引发错误,但会返回nil,然后是nil || []返回“你可以在它上面循环”的空数组(实际上循环为零)。

#2


5  

You could use a Null Object, something like:

您可以使用Null对象,例如:

class NullFamily
  def children
    []
  end
end

In your controller:

在你的控制器中:

@family = some_finder || NullFamily.new

Or you could pass a separate variable @children:

或者你可以传递一个单独的变量@children:

@family = some_finder
@children = @family.try(:children).to_a

And change your loop to:

并将您的循环更改为:

<% @children.each.with_index(1) do |family_member, index| %>
    // HTML HERE
<% end %>

#3


4  

How about this:

这个怎么样:

<% @family && @family.children.each.with_index(1) do |family_member, index| %>
    // HTML HERE
<% end %>

#4


1  

Maybe you can have this in your controller?

也许你可以在控制器中拥有它?

@family ||= []

#5


0  

You can use if @family.present? or the opposite as unless @family.blank?

您可以使用if @ family.present吗?或者相反,除非@ family.blank?