Rendering list items in Ruby on Rails 6
Tags: ror, rails, webdev, backend
Published: 2019-11-14 02:33:05

---
title: Rendering list items in Ruby on Rails 6
published: true
description: 
tags: ROR, Ruby On Rails, web development, backend
---


In web apps, we are all too familiar with the concept of looping over list items and displaying them to the user. Be it a list of products, users, articles, or some other entity.

In rails, we can display a list of items in the following ways. 

1) By putting a markup of each item in a file that also contains some other markup. Basically, the item markup is not in its own separate file.

2) By putting item markup into its own separate file (partial).

In this second option, we have two convenient ways to render each item in the list.

  - loop over the list and pass each item as a local variable into the item partial.
  - pass the entire list directly to the `render` method.

Let's see all of it in a little more detail.


# Putting item markup in a file that also contains some other markup

Imagine that we are running a men's suiting store and we have a suitings page on which we display *surprisingly* all the men suits via `suitings.html.erb` file.

```erb
<h1>Welcome to the Men's Clothing</h1>
<h2>We offer the finest men's suiting West of Atlantic</h2>
<p>While you are here paint the digital town red!</p>

<ul>
  <% @suitings.each do |suiting| %> 
    <li>
      <div><%= suiting.name %></div>
      <div><%= suiting.type %></div>
      <div><%= suiting.fabric %></div>
      <div><%= suiting.category %></div>
      <div><%= suiting.description %></div>
      <div><%= suiting.price %></div>
    </li>
  <% end %>
</ul>

<p>We hope you won't leave, without giving comfort to your body that it deserves!</p>

```

This is the first and the most straightforward way to display a list of items. We have `@suitings` instance variable coming from the `controller#action`. We loop over the list and display each item one by one.

# Problem with this approach

Currently, the markup for each list item housed in `<li>` tag is only a few lines long, so it doesn't matter much. 

But who is to say that our store won't become a big hit tomorrow and then we would have to render much more complicated list item markup, several lines long.

The product card may soon grow to contain checkboxes, radio buttons, drop-down, text-field, and other information about the product. Such a markup would naturally swell the list item template. 

Also currently we are dumping the list item template in a `suitings.html.erb` file that also has its own markup, such as the `<h1> <h2> and <p>` tags. Perhaps this page will also grow to contain more markup. 

Thus putting everything in one file can create a lot of mess and with time can become a maintenance nightmare. 

That is where the second form of list items rendering comes into play, where we separate the code out into its own partial.

But before we look at that, it helps to have a little detour about the partials. 

# What component is to the frontend *partial* is to the backend. 

If you have done any front-end dev with Vue, Angular or React you can think of a *partial* as a component. 

For instance, you can have a form, header, footer, product-card, table, etc. markup littered here and there in your Rails app. They can all be converted into their own standalone partials. 

These partials can be reused in multiple places very much like front-end components. 

You can even design these partials to be generic so that they can respond to variables being passed in from the outside. In doing so you will be defining a public API to communicate with the partial and thus can customize it according to the context in which it is used. 

We will look at a brief example of that at the end.

Having mentioned that, let's get back and look at the second way of rendering list items.

# Putting Item markup in its own separate partial 

Now we will create a separate partial `_suiting.html.erb` and put the relevant markup in there.


```erb
<li>
  <div><%= suiting.name %></div>
  <div><%= suiting.type %></div>
  <div><%= suiting.fabric %></div>
  <div><%= suiting.category %></div>
  <div><%= suiting.description %></div>
  <div><%= suiting.price %></div>
</li>

```

Now we can display a list of suitings in the `suitings.html.erb` with the following code

```erb
<ul>
  <% @suitings.each do |suiting| %>
    <%= render suiting %>		
  <% end %>
</ul>
```

Here, we are passing `suiting` as a local variable inside of the `_suiting.html.erb` partial.

But how does rails know which partial to use? We didn't tell that to the `render` method.

Rails figures that out on its own. It looks at the `suiting` variable and determines that it belongs to the `Suiting` class. 

So inside of the `views` directory, it looks for the `suitings` directory, inside of that it looks for `_suiting.html.erb` file.`views/suitings/_suiting.html.erb`. Rails does that all automatically.

With that, we have a cleaner code. Now we have our suiting template housed in its own partial and if tomorrow it grows and gets complicated it won't pollute other places.

But then there is even a better and lighter syntax to render a list of items. You don't even have to define the loop construct. You can directly pass the list to the `render` method.

```erb
<ul>
  <%= render @suitings %>
</ul>

```

Here again, rails will look at each item in the `@suitings` list, determine that it is instantiated from the `Suitings` class and will look  for the `_suiting_html.erb` partial and use that to render each item in the list. 

Here the instance variable name is `@suitings`. But it can be any name of your choice. You can name it `@men_clothes` and it would work just the same because each item in the collection is still of type `Suiting` or instantiated from the`Suiting` class. So Rails would look for the `_suiting_html.erb` partial to render each item.

# Making Suiting Partial/Component reusable

In closing, let's see how we can generalize `_suiting.html.erb` so that it can work with any product list such as sweaters, socks, pants and not only with suitings.

Firstly, we will rename our partial as `_product.html.erb` to make it more generic and make it work with any kind of product list. 

Also, we will move it into a shared directory `shared/_product.html.erb` because now it will be shared or reused in multiple places (putting in `shared` directory is not required but it's a common convention).

Secondly, we will have to refactor the markup as well

```erb
<li>
  <div><%= product.name %></div>
  <div><%= product.type %></div>
  <div><%= product.fabric %></div>
  <div><%= product.category %></div>
  <div><%= product.description %></div>
  <div><%= product.price %></div>
</li>

```

Here we are using `product` as the local variable, we will see why.

Now if we want to render a list of say @shorts we can do. 

```erb
<ul>
  <%= render partial: "shared/product", collection: @shorts %>		
</ul>
```

Here we have passed a configuration hash to the `render` method mentioning which list we want to render in our case `@shorts` using which partial in our case `_product.html.erb`. 

Inside the partial, each list item will be available under the same name as the partial name. Since, in our case, the partial name is `_product.html.erb`, each item inside the partial will be called `product`.


# Conclusion

There are three main ways to render lists inside the Rails templates. 

- Mixing item markup with another markup (not having its own separate file).
- Creating a separate partial for item markup.
- Generalizing the partial so that it can be reused in multiple places and work with any list.