Welcome to Giant Robots Smashing Into Other Giant Robots — a weblog about development, business, design and technology — written by thoughtbot.
Disambiguate rails helpers
Here at thoughtbot we strive to make explicit, agile code. We know the specification changes, it’s what we’re machined for. The place that changes the most, and is usually the hardest to maintain are the views. As my comrade pointed out the views usually run wild, so we use helper methods to prevent a long method chain, and keep things a little more readable. Sometimes however that usually leads to methods that aren’t used, or methods that are duplicated.
For example. Let’s assume you have a Blog, that belongs to a User, and has many Posts. Pretty standard right? There is no requirement for the Blog to have it’s own title so instead we use a helper method. On blogs#show we use a Blog helper method defined here:
1 2 3 4 5 6 7 |
module BlogsHelper def display_title_for(blog) "#{blog.user.name} - The Blog!" end end |
Good, now when a user clicks on a Post for that Blog, we get to posts#show. At the top of the page, we want to display the title of the Blog. So we try to call #display_title_for and get a NameError, something along the lines of undefined local variable or method.
We can’t use the method in the BlogsHelper from the Post’s views yet. We could go into the Post’s controller and add this:
1 2 3 4 5 6 7 8 9 |
class PostsController < ApplicationController helper :blogs def show @post = Post.find params[:id] end end |
I don’t like this solution, sure your being DRY, but your not being explicit. What happens when someone wants to change the display of the Blog’s title, and they are looking at the posts#show view? They will immediately look for a display_title_for(blog) in the Post’s helper – too bad it’s not there.
Another solution would be to duplicate the method on the PostsHelper. Although this also is a poor solution, if someone wants to change the way the blog title is being displayed, it will need to be changed in two spots.
So, I want helpers to be called explicitly, and defined explicitly. I want to know what is being called, and where it’s being called from. Let’s redefine the display_title_for(blog) on the BlogsHelper:
1 2 3 4 5 6 7 |
module BlogsHelper def self.display_title_for(blog) "#{blog.user.name} - The Blog!" end end |
Now that we have defined it as a module method we can use it in the post#show view like so.
BlogsHelper.display_title_for(@post.blog) |
Now we have explicit, dry, maintainable code.
About this entry
You're reading an entry on GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS, the company weblog of thoughtbot, inc.
- Author:
- Eric Torrey
- Published:
- July 24th 10:25 AM
- Updated:
- September 30th 09:53 AM
- Sections:
- Development
thoughtbot is hiring
We are hiring web developers and web designers in both Boston and New York, NY.
What are we up to?
We built Shoulda, an eclectic set of additions to Test::Unit; Paperclip to manage uploaded files without hassle; Jester, a REST/ActiveResource client library written in Javascript, and Squirrel, an enhancement for ActiveRecord's find syntax; — amongst some other projects.

Chad (President) and Jon (CTO) co-authored a technical book titled Pro Active Record: Databases with Ruby and Rails, which explores the ins and outs of the ActiveRecord ruby library. You can buy it today at Amazon.com.
About thoughtbot, inc.
We are a small web application development consulting business, with offices in Boston, MA and New York, NY. If you're looking to find a team for your next web development project or your new web application — get in touch.
10 comments
Jump to comment form