Using Rails 3.1, where do you put your "page specific" JavaScript code? Using Rails 3.1, where do you put your "page specific" JavaScript code? ruby-on-rails ruby-on-rails

Using Rails 3.1, where do you put your "page specific" JavaScript code?


The Asset Pipeline docs suggest how to do controller-specific JS:

For example, if a ProjectsController is generated, there will be a new file at app/assets/javascripts/projects.js.coffee and another at app/assets/stylesheets/projects.css.scss. You should put any JavaScript or CSS unique to a controller inside their respective asset files, as these files can then be loaded just for these controllers with lines such as <%= javascript_include_tag params[:controller] %> or <%= stylesheet_link_tag params[:controller] %>.

Link to: asset_pipeline


For the page-specific js you can use Garber-Irish solution.

So your Rails javascripts folder might look like this for two controllers - cars and users:

javascripts/├── application.js├── init.js├── markup_based_js_execution├── cars│   ├── init .js│   ├── index.js│   └── ...└── users    └── ...

And javascripts will look like this:

// application.js//= //= require init.js//= require_tree cars//= require_tree users

// init.jsSITENAME = new Object();SITENAME.cars = new Object;SITENAME.users = new Object;SITENAME.common.init = function (){  // Your js code for all pages here}

// cars/init.jsSITENAME.cars.init = function (){  // Your js code for the cars controller here}

// cars/index.jsSITENAME.cars.index = function (){  // Your js code for the index method of the cars controller}

and markup_based_js_execution will contain code for UTIL object, and on DOM-ready UTIL.init execution.

And don't forget to put this to your layout file:

<body data-controller="<%= controller_name %>" data-action="<%= action_name %>">

I also think that it is better to use classes instead of data-* attributes, for the better page-specific css. As Jason Garber have mentioned: page-specific CSS selectors can get really awkward (when you use data-*attributes)

I hope this will help you.


I see that you've answered your own question, but here's another option:

Basically, you're making the assumption that

//= require_tree .

is required. It's not. Feel free to remove it. In my current application, the first I'm doing with 3.1.x honestly, I've made three different top level JS files. My application.js file only has

//= require jquery//= require jquery_ujs//= require_directory .//= require_directory ./api//= require_directory ./admin

This way, I can create subdirectories, with their own top level JS files, that only include what I need.

The keys are:

  1. You can remove require_tree - Rails lets you change the assumptions it makes
  2. There's nothing special about the name application.js - any file in the assets/javascript subdirectory can include pre-processor directives with //=

Hope that helps and adds some details to ClosureCowboy's answer.

Sujal