문제

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