The Accelerate HR Blog
Little Helpers for Rails Helpers - 1 (Fri Dec 21 2007)
Somehow I'd never got round to using all those nice little helper files that Rails creates for you every time you generate a controller. Well, not quite true. I had created helpers, but done it the lazy way, borrowing other people's good ideas. Helpers to shortcut image display, to sort columns in a table (references at the end of the post) - but never helpers of my own.
Why not? Well Amy Hoy - as ever - explains it beautifully:
Form helpers are to be used in your application's views, including layouts and partials. It's that simple. Most helpers that come with Rails are meant to do something HTMLy, but it's not actually required that they spit out HTML. You can write helpers to use in controllers, if you so choose.
When you create your own, they go in one of the files in RAILSROOT/app/helpers/. But that's another article altogether.
You see? It's another article. And I haven't found it.
And there's another reason. Rails helpers are written in Ruby. They're Ruby helpers for Rails in fact. Now if you've been good boys and girls and read Pickaxe from cover to cover, then I'm sure helpers hold no mysteries for you. But for people like me, people who signed up for Rails thinking that Scaffolding would cut out the need for any serious programming, writing Helpers was ... well, not exactly what we had in mind. It's only recently, after several months of learning Ruby by osmosis as I worked on fattening up my models, that I looked at helpers again and thought ... I could do that.
So, here it is - the other article. In fact, not one, but ... more than one (four?) little helpers to show you how I came to use and love Rails Helpers - and how they've helped me to hang out my code to DRY. Starting with something very simple in this post, and then gradually getting a bit more complex.
Let's go back to Amy. Not just helpers, she says, but form helpers. And here's the key to understanding. Helpers are all about making it easy to simplify the form, to improve the view. To improve it so much in fact, that you achieve the ultimate goal: your grandmother takes one look at your view, smiles, sucks her tooth, and says 'That's nice dear, but haven't you forgotten about ....'
And the time to start thinking about helpers is when you start noticing that your views are getting unnecessarily complex, or you find that you're repeating the same line over and over.
For me, it started with dates, and in particular strftime.
If you've been here before, you'll know that I'm using Rails to build a complex HR application. And HR is stuffed with more dates than a Christmas pudding. Dates of birth, joining dates, leaving dates, vacation dates, absence dates, issue dates, expiry dates .... It doesn't help that I'm working with a multi-national team of administrators who all think about dates differently. The Filipinos think American: for them months come first. The Indians think European: it's days first for them. Given that I needed to migrate data from Excel, and that the team seemed to find it difficult to enter dates in any format recognized by Excel, you'll understand my concern about making sure that date-entries were crystal-clear to anyone using the database, no matter what their disposition.
I had two great tools. For data-entry it was DateTime Toolbocks, and for viewing and showing, it was strftime.
And here was the code that I typed 5 million times in my views:
The models and the field-names changed of course, but essentially it was the same 5 lines every time.
There were two issues here. First, strftime gives an error on a nil value - and that's why I needed the condition. Second, even after typing it 5 million times, my fingers still always screwed up on ("%d-%b-%y").
So that was 25,000,000 lines (possibly a slight exaggeration). Using my helper I was able to reduce it to 5,000,004. Whatever the actual numbers, that's a big reduction. And it was as simple as this.
The helper is just:
Ah you've noticed! I'm cheating. I could have reduced the entire 5-line condition in my view to 1 line using the same Ruby construction I've used in the helper. So it's not such a big saving at all. But the point is, I didn't. It's only as I've come to know Ruby better (and with constant pressure from the Rails community to DRY up the code) that I'm beginning to unlearn the tedious programing style I've been using for years. And starting with helpers is an ongoing part of the process.
And even so, I'm still reducing my typing by almost 50% and avoiding that nasty ("%d-%b-%y") combination, because all I need to include in the view now is:
Oh, where does the helper go? Not in the helpers generated with each controller obviously, or we'd be typing more than ever. But in application_helper.rb. Just add it once and it's available throughout your application.
So that was easy enough, right? Next time, we'll ramp it up a little.
I mentioned at the beginning a couple of helpers I've borrowed from other people. Check these out if you want to go a lot further with helpers than I've taken you here.
Four Days On Rails gave me a real kick-start with Rails when I read it 18 months ago. A little dated now, with new versions of Rails around, it remains full of good illustrative material, including a helper for displaying images - check out Adding a Helper on page 28 of the pdf.
I like sort_helper2 - Multiple Tables from Stuart Rackham and George Harkin, not only because it works well, but also because the documentation in the helper is an interesting tutorial in its own right.
Filed under: Ruby on Rails
Rob - your advice is gratefully accepted - and both the article and the database are better as a result. Thanks for being a good helper.
It should be noted that the h() call above is unnecessary. That call ensures HTML-ness of arbitrary text - but your text isn't arbitrary. It's well formatted or nothing. So drop the h() and speed things up. Also, you don't need the "dateshown = " at the start of your fdate() method. It's redundant. Cheers!