Using a Rails helper method within a javascript asset

JavascriptRuby on-RailsRuby on-Rails-3Asset PipelineErubis

Javascript Problem Overview


Is there any way to use a Rails helper method, more specifically, a path helper method within a javascript asset file. This file foo.js.coffee.erb

$('#bar').val("<%= create_post_path %>")

I would love it if I could get from erubis

$('#bar').val("path/to/create")

Javascript Solutions


Solution 1 - Javascript

You can include any helper/module/class in an erb template with:

<% environment.context_class.instance_eval { include MyHelper } %>

See: https://github.com/rails/sprockets/blob/master/lib/sprockets/environment.rb and https://github.com/rails/sprockets/blob/master/lib/sprockets/context.rb

To use the url helpers you have to include your specific applications' helpers.

They are available at Rails.application.routes.url_helpers so:

<% environment.context_class.instance_eval { include Rails.application.routes.url_helpers } %>

EDIT: Fixed links to moved sprockets repo but not really sure this still makes sense so many years later.

Solution 2 - Javascript

This will also do the trick in an initializer:

Sprockets::Context.send :include, MyHelper

In development mode the helper will not be reloaded on every request.

Your approach with UrlHelpers will work until you need to find post_path(...um...we don't know what post id we'll need at compile time...). There is a ruby gem which reimplements all of your Rails UrlHelpers in JavaScript: https://github.com/railsware/js-routes

Solution 3 - Javascript

I'm not quite sure, why you want to do this.

  • You would prevent the javascript file from being cached, as it contains a dynamic value

  • You would get a coupling between your javascript/coffeescript and rails

If possible I would advice you to abstract your problem away by providing your target path in the view and retrieve the value from the DOM-Element when the specific event occurs. Just like 'Unobtrusive Scripting Adapters' for Rails do. E.g.: https://github.com/rails/jquery-ujs/blob/master/src/rails.js#L157-173

Solution 4 - Javascript

Indeed I agree with @eirc answer (taking into account Sprockets documentation). But I would consider including helper modules at rails boot time. As per

# config/initializers/sprockets.rb
Rails.application.assets.context_class.instance_eval do
  include ActionView::Helpers
  include Rails.application.routes.url_helpers
  include MyModule
end

this is because of: https://github.com/rails/sprockets-rails/blob/master/lib/sprockets/railtie.rb#L23

Solution 5 - Javascript

Actually, not sure if this helps but there is a way to define your own helpers for use during rake precompile

Create a new initializer and put this in it:

module Sprockets
  module Helpers
    module RailsHelper

      def my_helper_method
       ...
      end

    end
  end
end

And then you can:

<%= my_helper_method %>

in your .erb assets

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
QuestionaxsuulView Question on Stackoverflow
Solution 1 - JavascripteircView Answer on Stackoverflow
Solution 2 - Javascriptuser1158559View Answer on Stackoverflow
Solution 3 - JavascripttopekView Answer on Stackoverflow
Solution 4 - JavascriptAndrea AmantiniView Answer on Stackoverflow
Solution 5 - JavascriptMatthewView Answer on Stackoverflow