问题
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?
回答1:
Bad news, render is not available Look: same question on GitHub
回答2:
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.
回答3:
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
回答4:
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.
回答5:
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
回答6:
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.
来源:https://stackoverflow.com/questions/7336072/rendering-a-partial-in-assets