2

In Ruby on Rails v4, I want a js file (or set of js files) to be only loaded for a particular controller.

What is the standard way to do this?

In application.js there is the //= require tree . line. I'm assuming this would need to be removed so I'm not always loading every file. But then what? Will a file named mycontroller.js always be loaded when Mycontroller is used?

Don P
  • 60,113
  • 114
  • 300
  • 432
  • Before trying to split up your JavaScript for individual controllers you should know that the JS files (and other assets like CSS and images) are usually not loaded on every request because they're cached by the browser. – Koraktor Nov 11 '13 at 05:52
  • Further to Koraktor, it depends on how you have your asset pipeline set up. The caching will happen if your assets are rendered on the fly, but if they are static, you'll have to cocern yourself with Turbolinks – Richard Peck Nov 11 '13 at 09:59
  • Same rails 3: http://stackoverflow.com/questions/6167805/using-rails-3-1-where-do-you-put-your-page-specific-javascript-code – Ciro Santilli OurBigBook.com Jul 14 '14 at 09:20

2 Answers2

4

The asset pipeline can be very powerful if you do it right:

Manifests

The purpose of //= require tree . is to create a "manifest" file which Rails will use to render the files you call. If you don't "precompile" your assets, this means that each time your browser loads your app, it will look for the files contained in your manifest & load them

This means that you can define what you call in your manifest & what you don't. We prefer to call any gem-based assets in the manifest, but also designate specific folders, like this:

//
//= require jquery
//= require jquery_ujs
//= require jquery.ui.draggable
//= require_tree ./jquery
//= require_tree ./extra
//= require turbolinks

We use this setup to call all JQuery plugins & any extra JS, as well as the gem-specific files


Precompiling

If you pre-compile your assets, it basically builds different files which are loaded consistently when you load the browser. If you're using Heroku or a CDN, you may wish to precompile your assets, as to reduce latency & dependency


Application Design

To answer your question, you can certainly load controller-specific JS. We do it like this:

#app/views/layouts/application.html.erb
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
<%= stylesheet_link_tag controller_name, media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag controller_name, "data-turbolinks-track" => true %>

You can then ensure your JS files are split up by using what Phoet described:

#config/environments/production.rb
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
config.assets.precompile += %w(mycontroller.js)

Then for application.js, you can only call the files you want to persist throughout the app:

#app/assets/javascripts/application.js
//
//= require jquery
//= require jquery_ujs
//= require jquery.ui.draggable
//= require_tree ./jquery
//= require_tree ./extra
//= require turbolinks
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
1

It works like this:

You define additional files that should be precompiled:

# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
config.assets.precompile += %w(mycontroller.js)

Then in your layout you implement some logic to include this file:

= javascript_include_tag "#{controller_name}.js" if controller_name == 'mycontroller'
juffel
  • 1,045
  • 15
  • 21
phoet
  • 18,688
  • 4
  • 46
  • 74