Cristian
Cristian

Reputation: 6077

Use Rails Sprockets directives when rendering js from controller

I want, from a controller, to render a .js.coffee view that includes another js file from the lib/assets/javascripts directory:

#= require doc_ready

Why a view rendered by a controller instead of a static asset?

Because I want to refer to the file through an absolute url, that doesn't changes. Rails 4.0 only compiles assets with a digest like embed-dc589fbef3832d9c38a4fbbc4b021f59.js and I want to use the same url (and possibly expire the cache file based on time), even if I make changes to the script.

Why an absolute url?

Because I want to use the script externally on another website, and the code I give to the webmaster of that site mustn't change.

Why do I want to include another js from the assets?

  1. To keep the code DRY
  2. To require a simple library that simulates the jquery ready event, used to create widgets on the page that included the script.

Can I achieve that by making a controller action that renders a .js.coffee view, which compiles and includes other needed js files from the library, just like sprocket does when compiling assets?

Upvotes: 2

Views: 385

Answers (3)

methyl
methyl

Reputation: 3312

Use redirection like so:

  def show
    redirect_to view_context.javascript_path('embed.js.coffee')
  end

There is a way to render whole js file:

def show
  render text: Rails.application.assets.find_asset('embed.js.coffee').body
end

Upvotes: 1

Frederick Cheung
Frederick Cheung

Reputation: 84114

Another approach is to symlink or copy the digest version of the asset to some constant path (and give that to the 3rd party). This has the advantage that the requests shouldn't hit rails at all (since these should be served directly by the web server.

It is relatively simple to automate this - two libraries that I am aware of that do this are

Upvotes: 0

Cristian
Cristian

Reputation: 6077

I managed to find a way to do it, by using this answer.

The controller is left untouched:

class Widgets::EmbedJsController < ActionController::Base

  def embedded_script

  end

end

In the coffeescript view, I have "required" the other file like this:

`<%= raw Rails.application.assets['doc_ready'].body %>`

Seems to work locally, I'll test in production soon.

This can also be refactored by just serving Rails.application.assets['widgets/embed'].body directly from the controller, which should compile coffeescript but have not tested it.

Upvotes: 1

Related Questions