Ruby iterates over a variable if it is not zero

I would like a clean .html.erb to loop through a variable ONLY if the variable is non-zero.

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

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

I try to avoid doing something like this

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

And especially try to avoid the need

 <% 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?

+4
source share
5 answers

This solution may be misleading, but the Ruby syntax allows you to do this:

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

I use this solution only for simple operators, such as checking for the presence of an object (for example, in your case). I do not recommend this solution for more complex logic , because a third party does not know that the condition is at the end of the block.


Other:

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

If @family is nil , try(:children) does not result in an error, but returns nil , and then nil || [] nil || [] will return an empty array, which "you can loop on it" (the cycle on it is zero times actually).

+5
source

You can use a Null Object , something like:

 class NullFamily def children [] end end 

In your controller:

 @family = some_finder || NullFamily.new 

Or you can pass a separate variable to @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 %> 
+5
source

How about this:

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

Perhaps you can have this in your controller?

 @family ||= [] 
+1
source

Can you use if @ family.present? or vice versa, if only @ family.blank?

0
source

All Articles