Using helper methods inside your controllers

Anderson Dias
Little programming joys
2 min readDec 10, 2015

--

Have you ever needed to use a helper method inside your controller? I did, a few times. If you included the helper module inside the controller, as I did many times before, you did it wrong.

Imagine you have an action that receives a query param and this param should be sanitized before you pass it to your search lib. Unfortunately, there is no sanitize instance method for String, but you rely on ActionView::Helpers::SanitizeHelper#sanitize method and want to use it inside your controller.

The first thing I tried was to invoke the helper method directly from the action method:

class SomeController < ApplicationController
def some_action
@query = sanitize(params[:q])
@search_result = ExternalLib.search(@query)
end
end

Ops… it raises:

NoMethodError: undefined method `sanitize’ for #<SomeController>

What to do next? The second solution that come to my mind is to include the helper inside the controller.

class SomeController < ApplicationController
include ActionView::Helpers::SanitizeHelper
def some_action
@query = sanitize(params[:q])
@search_result = ExternalLib.search(@query)
end
end

Ta-da! It works! But think about it for a while… what happens when I include a module inside my controller?

Including a helper module inside your controller will expose every helper method as an action in your controller.

I’m pretty sure you don’t want that!

Another solution for this problem

There is a better approach do solve this problem:

class SomeController < ApplicationController
def some_action
@query = ActionController::Base.helpers.sanitize(params[:q])
@search_result = ExternalLib.search(@query)
end
end

Instead of including the helper module inside the controller you can use the ActionController::Base.helpers available inside your action to have access to every helper method you use inside your views!

If you use the include approach in newer Rails applications I strongly suggest you to replace all the includes.

Happy coding!

EDIT: I’m avoiding to use view_context because it instantiates a new view instance per call.

--

--