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 .
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.