Using helpers in controllers

We all know that we should code keeping MVC in mind. It is not a good idea to mix C(controller) and V(view). However time to time we are forced to push to the limit.

One such case could be when you want to use link_to method in controller. link_to is defined in actionpack/lib/action_view/helpers/url_helper.rb .

One easy way is to include that class file in controller like this.

 
# environment.rb
include ActionView::Helpers::UrlHelper 

Life is good but soon you need pluralize method in your controller and slowly the include files might look like this.

 
# environment.rb
include ActionView::Helpers::UrlHelper 
include ActionView::Helpers::SanitizeHelper 
include ActionView::Helpers::TextHelper 
include ActionView::Helpers::DebugHelper
include ActionView::Helpers::TagHelper

This is not good.

I came across this post from “Hungry Machine” and he has posted an excellent solution .

 
ActionController::Base.class_eval do
  def with_helpers(&block)
    template = ActionView::Base.new([],{},self)
    template.extend self.class.master_helper_module
    add_variables_to_assigns
    template.assigns = @assigns
    template.send(:assign_variables_from_controller)
    forget_variables_added_to_assigns
    template.instance_eval(&block)
  end
end

Usage

 
class MyController < ApplicationController
  def my_action
    @person = Person.find(params[:id])
    render :text => with_helpers { link_to(@person.full_name,
    person_path(@person)) }
  end
end

This is an excellent solution. Now we don’t need to include anything in enviroment.rb .

If you want to know what master_helper_module is and how the above code is doing what it is doing then you should read this and this .

Comments

What about self.class.helpers.link_to(“Pr0n”, pr0n_path)? It’s available for a while now :)

Jacek,

I totally missed that one. Didn’t know about helpers. I will check that out.

Post a new comment




Wrap code in <pre> ... </pre>

My name is Neeraj. You can contact me at neerajdotname@gmail.com . I am also on twitter , facebook and Linkedin .

admin_data , active_record_no_table , session_expiration_management , always_at_bottom and javascript_lab are some of my projects on github .