Using helpers inside controllers in Ruby on Rails

Rails provides some nice helper functions (numbers, dates, etc.) that are available to views, but they’re not automatically available to controllers. I found a number of ways to accomplish this on the web, but I wasn’t satisfied with any of them.

The motivation for me to do this was to use the number_to_currency() helper function in a controller, so I’ll use that for the example. This helper is in the ActionView::Helpers::NumberHelper module, which on my Ubuntu 7.04 system is located here:

/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_view/helpers/number_helper.rb

It may be located elsewhere on your system. If you’re running *nix (or OSX), then typing the following command should locate it:

locate number_helper.rb

If you edit number_helper.rb, you’ll notice that NumberHelper is a module and number_to_currency() is an instance method, so we’ll need an instance that has included NumberHelper to be able to call the number_to_currency() method.

One way to do this would be to create a new class that includes the module, and then create an instance of that class:

class MyNumberHelper
include ActionView::Helpers::NumberHelper
end
my_helper = MyNumberHelper.new
formatted_str = my_helper.number_to_currency(n)

If we had an existing object, called obj, another way to accomplish this would be via:

obj.extend(ActionView::Helpers::NumberHelper)

Since I didn’t have an appropriate object to extend the NumberHelper module, I simply created a new one:

Object.new.extend(ActionView::Helpers::NumberHelper)

If I only need to call the helper once, I could accomplish that via:

Object.new.extend(
ActionView::Helpers::NumberHelper).number_to_currency(n)

However, I preferred to create a Proc object and store it for future use:

format_currency = lambda { |n|
Object.new.extend(
ActionView::Helpers::NumberHelper).number_to_currency(n) }

format_currency.call(n)

UPDATE: it’s not necessary to use the lambda (as cool as they are), simply storing the result of Object.new.extend(ActionView::Helpers::NumberHelper) is sufficient. For example:

x = Object.new.extend(ActionView::Helpers::NumberHelper)
x.number_to_currency(7.4)
# results in "$7.40"

END UPDATE

I deliberately wanted to avoid simply including ActionView::Helpers::NumberHelper in the controller to avoid polluting the namespace and possibly expose additional public methods in the controller.

Tags: , ,

  1. Attila’s avatar

    Thanks, helped me out. First time I heard of lambda, too. Yes, i am that much of a rookie in ruby world. :)

  2. vinhboy’s avatar

    Thanks for this. I am using it with my app. However, I can’t help but feel this is some how the wrong way to things. There has to be a reason why helpers are not accessible in controllers right???

  3. Brian Adkins’s avatar

    @vinhboy why would you want an arbitrary function available to a view but not a controller ?

  4. Chris Cera’s avatar

    The simple method in your last update solved my problem. Thank you. -Chris

  5. kumar deepak’s avatar

    include the helper module in application controller

    e.g.
    class ApplicationController < ActionController::Base
    protect_from_forgery
    include SessionsHelper
    end