Rendering a partial in assets
Asked Answered
H

6

7

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?

Halftrack answered 7/9, 2011 at 15:1 Comment(0)
Y
8

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

Yorgen answered 6/10, 2011 at 13:50 Comment(0)
C
5

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.

Complainant answered 2/12, 2011 at 22:20 Comment(0)
R
1

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
Reprehension answered 11/7, 2014 at 3:19 Comment(1)
For some reasons render puts a new line at the end and makes js code invalid. Fixed by adding chomp after renderMoramorabito
A
1

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.

Ancylostomiasis answered 14/1, 2016 at 18:44 Comment(0)
F
1

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

Florafloral answered 14/9, 2016 at 12:35 Comment(0)
U
-2

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.

Unseemly answered 25/11, 2012 at 19:32 Comment(1)
What ? How can it be that giving a different parameter to a method making it available ?? Do you have a working example somewhere ?Gamboa

© 2022 - 2024 — McMap. All rights reserved.