January 24th, 2007

I stumbled today on an apparently little-known method in Rails, which solved a problem that has been vexing me for months: how to use helper methods from controllers/models/views/whatever other than the one you’re currently working in. No amount of Googling or begging for suggestions in the (mostly useless) #rubyonrails IRC channel could do me any good.

Ok, so on Lovetastic, we have an account dashboard which pulls together lots of information from different models. This dashboard (for now anyway) rests in AccountController. However, I want to use a formatting helper to display a human-friendly version of people’s subscription expiration dates, the code for which rests in SubscriptionHelper. And I don’t want to have to duplicate any code to do it.

The helper in question, natch, is associated with a separate controller, so its methods don’t get mixed into the AccountController. So I had been trying all sorts of stupid and ugly hacks to include that helper code cleanly into the AccountController’s dashboard view. I tried using shared partials, raw ruby includes, and a couple even more arcane backflips, to no avail.

Then, with hours of sufficiently creative Googling, I was able to turn up a super-tidy Rails Way™ to do this.

1
2
3
4
5
class AccountController < ApplicationController
  helper :subscription

  ...
end

And, bam. There you have it. You can now use all the helper methods in SubscriptionHelper anywhere in an AccountController template.

Who knew?

7 Responses to “Sharing helpers between controllers”

  1. Pat Maddox Says:
    Agile 2, p472, "Sharing Helpers" Lots of other good stuff in there :)
  2. Ryan Norbauer Says:
    Well, haven't quite gotten around to *re*reading the Agile book in its 2nd edition, though the new version it is sitting on my desk now. And I do sort of have that intent. It's on the someday/maybe list. Oh well. This helper inclusion business was news to me. And for some reason it was hard to come up with the google terms to get my answer. So I thought I'd add to the keyword heap.
  3. JD Says:
    Asking JD > #rubyonrails :)
  4. Walter McGinnis Says:
    An alternative, albeit an ugly one, is to do your shared helpers in app/controllers/application.rb or app/helpers/application_helpers.rb. I'm doing that now while I'm in early development mode, but plan on "extracting" things out it into more logical modules or into more specific helpers down the line. Cheers, Walter
  5. Keeran Says:
    I noticed this technique while going through the Beast source - I didn't know what it did until reading this, so thank you! By the way, the last paragraph, should it say: "You can now use all the helper methods in SubscriptionHelper anywhere in an AccountController template." Thanks again, Keeran
  6. Ryan Norbauer Says:
    Thanks Keeran! :)
  7. Eleo Says:
    One difficulty seems to come from rendering templates. Unless I'm doing something wrong you now have to specify them by the root of the helper directory such as render(:partial => '/controller/template') as opposed to render(:partial => 'template') or they can't be found.

Leave a Reply