Looping through a list

what is the proper way to loop through a list in a rails view (assuming
that you need to check if it is empty or not)

my_list.each do | an_item |
puts “#{an_item}”
end

If the list is empty nothing is printed.

Paul H. wrote:

my_list.each do | an_item |
puts “#{an_item}”
end

If the list is empty nothing is printed.

should i return my lists from the model?

<%- @records.each do |record| -%>
here you handle each record, doing what has to be done
<%- end -%>

If @records is an empty array or other Enumerable, then the inside of
the loop will never be executed. If @records is nil, you’ll throw an
error.

If you just want to remove all empty elements in your array, before
looping, you can just do this in your controller:

@records.compact!

This removes all nil elements. Then when you loop through it in the
view, you only get real records.

Scenario 1:

Find all the models on your index page.

def index
@items = MyModel.find(:all)
end

index.html.erb:

    <% @items.each do | an_item | %>
  • <%= an_item.some_value %>
  • <% end %>

Scenario 2:

class MyModel < ActiveRecord::Base
has_many :other_models
end

class OtherModel < ActiveRecord::Base
belongs_to :my_model
end

Find all children for a given model using has_many

def show
@the_parent = MyModel.find(params[:id])
end

show.html.er:

<%= @the_parent.some_value %>

<% @the_parent.other_models.each do | a_child | %>

<%= a_child.some_value %>

<% end %>

Scenario 3:

class MyModel < ActiveRecord::Base
acts_as_tree
end

Find all children in the heirarchy

def show
@the_parent = MyModel.find(params[:id])
end

show.html.erb:

<%= @the_parent.some_value %>

<% @the_parent.children.each do | child | %>

<%= child.some_value %>

<% end %>

In all these scenarios if the list is empty (i.e. none were found, there
are no children in a has_many relationship, or no children in a tree)
then the “each” blocks print nothing. You don’t need to test to see if
the list is empty (unless you want to explicitly print something like
“No values” if the list is empty).

Testing if the list is empty you could use the “size” method on the
returned collection.

Generally, if you are going to display a list of things (for example all
the items from a query) you will process the list inside an erb/rhtml
file.

If you use a find(:all, …) method you will get back a collection of an
empty collection. If you navigate a relationship you will get a
collection or an empty collection. Generally, in rails, methods that
return a collection will return an empty collection, not nil.

If, however, you have code like:

def some_action
@thing = MyModel.find(params[:id])
if @thing.some_test
@list_of_stuff = @thing.children
end
end

Then you would need to test @list_of_stuff to see if it’s nil. But
that’s probably bad form.

Paul H. wrote:

If you use a find(:all, …) method you will get back a collection of an
empty collection. If you navigate a relationship you will get a
collection or an empty collection. Generally, in rails, methods that
return a collection will return an empty collection, not nil.

If, however, you have code like:

def some_action
@thing = MyModel.find(params[:id])
if @thing.some_test
@list_of_stuff = @thing.children
end
end

Then you would need to test @list_of_stuff to see if it’s nil. But
that’s probably bad form.

thanks guys. I found that my problem was that i was using find_all_by
incorrectly and it was returning nil.

Brent M. wrote:

<%- @records.each do |record| -%>
here you handle each record, doing what has to be done
<%- end -%>

If @records is an empty array or other Enumerable, then the inside of
the loop will never be executed. If @records is nil, you’ll throw an
error.

If you just want to remove all empty elements in your array, before
looping, you can just do this in your controller:

@records.compact!

This removes all nil elements. Then when you loop through it in the
view, you only get real records.

so should I always do a nil check on @records before I loop through the
records?