Ruby迭代变量,除非它是零

时间:2015-08-18 16:58:30

标签: ruby-on-rails ruby ruby-on-rails-4 erb

如果变量不是nil,我想在.html.erb中使用一个干净的方法来循环变量。

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

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

我试图避免做这样的事情

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

特别是试图避免需要

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

有更好的方法吗?

5 个答案:

答案 0 :(得分:5)

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

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

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

另一个:

<% (@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| %>

如果@familynil,则try(:children)不会引发错误,但会返回nil,然后nil || []会返回空数组&#34;你可以循环它&#34; (实际上循环零次)。

答案 1 :(得分:5)

您可以使用Null Object,例如:

class NullFamily
  def children
    []
  end
end

在您的控制器中:

@family = some_finder || NullFamily.new

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

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

将你的循环改为:

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

答案 2 :(得分:4)

这个怎么样:

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

答案 3 :(得分:1)

也许你可以在控制器中使用它?

var fund = 
    context.Funds
           .Include(f => f.Owner)
           .FirstOrDefault(f => f.FundId == newTransaction.ToFund.FundId);

答案 4 :(得分:0)

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