This week I was working on a Rails application and stumbled across a really cool trick for rendering collections. As per the usual, it involves a little Rails magic as you’ll see. This trick will clean up a lot of your views and adheres to our coveted DRY convention.
Imagine you’re working on an application and you’ve got a collection of users you’d like to display. You might so something similar to this (Rails generated this when I used the generate scaffold command) to display all of your users.
This will work but I believe we can do better. To clean up the code we’ll create a partial and then simply render it. This is where the magic happens.
Creating Your Partial
To create the magic we need to keep in mind a few things when we create the partial.
- The collection you pass to the view (@users, @todoItems, @etc) will determine what you need to name your partial.
- Your partial needs to be the singular version of the collection. Rails will look for that name specifically. Pretty smart eh?
Okay, with those things in mind we can create the partial. Since my collection is @users I’ll give my partial the name _user.html.erb. Once inside the partial, I’ll have access to the instance variable user and I can access its variables from there.
<span class="name"><%= user.name %></span>
<span class="bio"><%= user.bio %></span>
Rendering the Partial
This is the easiest part. Delete or comment the previous code you were using to render your collection and add the following.
<%= render @users %>
A lot less code huh? It’s a little bit of Rail’s voodoo I admit but doesn’t that look nicer? You can even use this method for heterogeneous collections but I won’t be covering that today. After adding that code and a little styling my view looks like this.
You can download the code on GitHub here.
That wraps it up. If you enjoyed this post please share it with somebody else you think could benefit. Also, if you didn’t find this helpful or think it could be improved let me know! To reach me just leave a comment or shout out to me on Twitter @josh_qn.
Thanks again! Auf wiedersehen!