Referencing Rails Assets in CoffeeScript

Sometimes you’ll want to refer to your image assets from inside of your CoffeeScript (or JavaScript). While we have nice helpers for that in SASS (namely image-path and image-url), we would have to resort to appending .erb to every .js or .coffee file, we want to reference images in, so that we could use something like this in there:

icon = <%= image_path('icon.png') %>

I didn’t like it that way, because ERB inside of CoffeeScript looks odd and having the file end with .erb messes up syntax highlighting. But we can circumvent this easily by adding this (admittedly not the most beautiful) piece of code to one single file that ends on .erb (i.e. and let it provide the helper method we need:

imgs = {}
Dir.chdir("#{Rails.root}/app/assets/images/") do
  imgs = Dir["**"].inject({}) {|h,f| h.merge! f => image_path(f)}

window.image_path = (name) ->
  <%= imgs.to_json %>[name]

This adds up all images inside of app/assets/images and makes them available via the global helper method image_path - your milage may vary, but you get the idea. From there on it’s simply

icon = image_path('icon.png')

inside of your CoffeeScript (or JavaScript) files and it also works in production as the returned filename contains the digest.