I'm using Ruby on Rails 3.1 and I'm wondering how I could render a partial in a javascript asset.

What I'm aiming at:

# in /app/assets/javascript/cart.js.coffee.erb
$('a.add_sth').click -> $('.random_container').append('<%= render partial: 'way/to/partial' %>')

This causes a NoMethodError:

undefined method `render' for #<#<Class:0x007fc54584c6e8>:0x007fc5474cd470>

If I write <%= 2+3 %> instead it works fine, btw.

I think the problem is that the asset pipeline is independent from the default ActionView and that's why render() is unknown there. Anyway, is there a way to get that partial's content rendered?

有帮助吗?

解决方案

Bad news, render is not available Look: same question on GitHub

其他提示

Remember that assets are meant for static data, like CSS, JS or images that will not dynamically change its contents, so they can be better cached and/or exported to a CDN.

Since you are allowed to run ERB with ruby code, it should always return the same value (since it will be executed only when compiling the asset).

That's why I guess render is not available inside assets (although it could be properly used to render static data).

Easy solution here: move your JS file to a view, there you will be able to use any view helper.

This worked for me. (for HAML)

= Haml::Engine.new(File.read(File.join(Rails.root, 'app/views/xxxxx','_form.html.haml'))).render(Object.new, :hello => "Hello World")

And, needed to add dependency in the beginning of file to be updated like: In this case, the depended file is needed to be in the asset.

//= depend_on xxxxx/_form.html.haml

In rails 4.2

I found this post https://github.com/sstephenson/sprockets/issues/90 which suggests using <% require_asset 'path/to/file' %>

This worked for me.

I had similar issue, so I wrote this render method, that can be used inside assets to render ERB partial template:

# in lib/my_app/erb_helpers.rb
module MyApp
  module ERBHelpers
    class << self

      def render(partial_path, binding)
        dir_name, _, partial_name = partial_path.rpartition(File::SEPARATOR)
        file_name = "_#{partial_name}.html.erb"
        Erubis::Eruby.new(File.read(File.join(Rails.root, 'app', 'views', dir_name, file_name)).gsub("'", %q(\\\'))).result(binding)
      end

    end
  end
end

Then I used it inside coffeescript file like this:

# in app/assets/javascripts/notifications.coffee
MyApp.notifications.templates =
  notice: '<%= ::MyApp::ERBHelpers.render 'application/notifications/notice', content: "%content%" %>'
  alert: '<%= ::MyApp::ERBHelpers.render 'application/notifications/alert', content: "%content%" %>'

MyApp.notifications.create_elem = (type, content) -> MyApp.notifications.templates[type].replace('%content%', content)

PS: I tested it on Rails 5.0 app

In fact, it works for me. You need to do:

= render 'way/to/partial'

where 'way/to/partial' is relative path under existing assets folder. Wired thing is that in the path, you need to omit the first level folder under assets.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top