Rendering collections

Like anything as a developer, there are many ways to accomplish the same task.

While making some updates to code and doing some refactoring, I couldn't help but notice a smell in our logs. I hadn't really thought much about it before, but it caught my eye this time - for whatever reason.

For a code base that's been alive for two+ years, there are quite a few spots that we just haven't felt the need to touch. We've refactored heavily over the past few months, but we haven't touched everything. Our churn is almost 0 in some files for no particular reason.

This particular code smell showed up in our logs. It's a spot where we render a collection with some partials. More specifically, it's a place where we render comments for a particular user. Looking at the code now, it's obvious what we should do to improve it.

For the record, it's a file we haven't changed in over a year. And better yet, the 2nd time it's ever been changed was in late 2011.

Here's what I'm talking about:

Currently, we're using Example 1 to render comments. I've shown the code smell in the logs. My first question: Why do we need to render all of these partials? There's an obvious reason in that we have many comments. But, there must be a better way.

Use the built-in methods for rendering a collection

Most of you probably know that Rails offers a built-in way to render a collection of items with a partial. It's even optimized for you.

In Example 1, Rails doesn't know you're trying to render a collection. It simply does what you ask of it. Loop and render the item each time. It's not smart enough to tell you there's a better way.

In Example 2, you're simply providing a collection and letting Rails iterate. Not only will it iterate for you, it does it in a smart way.

In partial_renderer.rb above, there's a branching case where it checks for a collection you provide. If it sees one, it takes a slightly different approach.

It caches the partial and maps the results of the collection. It's something you can let Rails worry about.

You can see the results in the logs above. In Example 1, it looks up the partial 3 times and renders it. In Example 2, there's only one look up. You can imagine how this gets cumbersome if you're trying to render hundreds of comments.

Example 1 is O(n) in regards to looking up your partial. Example 2 is O(1). Although, to be fair, Example 2 will still have to render each partial with the proper data. Example 3 is just another way to write Example 2 (if you follow the the proper naming conventions).