How to mixin and call link_to from controller in Rails?

Ruby on-RailsHelpersActionviewLink ToMixins

Ruby on-Rails Problem Overview


This seems like a noob question, but the simple answer is eluding me. I need to call link_to in an ActionController method to spit out an HTML link. ActionView::Helpers::UrlHelper.link_to calls url_for, but this calls the AV module's version instead of the controller's. I managed to coerce this into doing what I intended by putting

  #FIXME there must be a better way to mixin link_to
  alias_method :self_url_for, :url_for
  include ActionView::Helpers::UrlHelper
  alias_method :url_for, :self_url_for

in the controller. But, I'm still not sure why it works exactly. Could someone please explain the method scope and hiding that's happening here? What's a better way to mix in link_to (or generally, to include only some methods from a module) so I can call it in the controller (generating a flash string with a link is the use case.)

Please, no lectures about MVC--if anything, link_to should be in a module separate from url_for. Judging from the amount of noise on this, lots of people run into this seemingly trivial snag and end up wasting an hour doing it the "Rails way" when really what is wanted is a one minute hack to make my app work now. Is there a "Rails way" to do this with helpers perhaps? Or a better ruby way?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

Compatible with Rails 3,4 and 5:

view_context.link_to

Solution 2 - Ruby on-Rails

This doesn't really answer your question but there is an easier way

For Rails 5, use the helpers proxy

helpers.link_to '...', '...'

For Rails 3 and 4, since you are using the helper from a controller you can use the view_context

# in the controller code
view_context.link_to '...', '...'

# instead of using your mixin code 
link_to '...', '...'

For Rails 2, since you are using the helper from a controller you can actually access the @template member variable of the controller, the @template is the view and already has the UrlHelper mixed in

# in the controller code
@template.link_to '...', '...'

# instead of using your mixin code 
link_to '...', '...'

if you need to use the urlhelper from code other than the controller, your solution is probably the way to go

Solution 3 - Ruby on-Rails

You can do it like this:

ActionController.helpers.link_to("Click Me!", awesome_path)

But really, a better place to generate that link might be in a helper module where UrlHelper and other view-related helpers are already included.

[update]

This approach is outdated and no longer works.

Solution 4 - Ruby on-Rails

I still had problems using my own helper methods that use built-in helper methods in a controller with ActionController.helper.my_method.

Obviously using render_to_string for each flash would work, but I don't want to create so many small partials for each flash.

My solution was to create a little helper for controllers to execute code in a partial.

The helper method in the controller:

def h(&block)
  render_to_string(:partial => 'helper', :locals => {:block => block})
end

The HAML partial (helper.html.haml):

= instance_eval &block 

Same would work in ERB (helper.html.erb):

<%= instance_eval &block %>

Use it like this in your controller to call the my_custom_helper_function that's defined in a helper:

redirect_to url, :notice => h{my_custom_helper_function}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiontribalvibesView Question on Stackoverflow
Solution 1 - Ruby on-RailsYacine ZalouaniView Answer on Stackoverflow
Solution 2 - Ruby on-Railshouse9View Answer on Stackoverflow
Solution 3 - Ruby on-Railsbrentmc79View Answer on Stackoverflow
Solution 4 - Ruby on-RailsSascha KonietzkeView Answer on Stackoverflow