To my understanding, all of your JavaScript gets merged into 1 file. Rails does this by default when it adds //= require_tree .
to the bottom of your appl
Paloma project offers interesting approach to manage page specific javascript code.
Usage example from their docs:
var UsersController = Paloma.controller('Users'); // Executes when Rails User#new is executed. UsersController.prototype.new = function(){ alert('Hello Sexy User!' ); };
<%= javascript_include_tag params[:controller] %>
Philip's answer is quite good. Here is the code to make it work:
In application.html.erb:
<body class="<%=params[:controller].parameterize%>">
Assuming your controller is called Projects, that will generate:
<body class="projects">
Then in projects.js.coffee:
jQuery ->
if $('body.projects').length > 0
$('h1').click ->
alert 'you clicked on an h1 in Projects'
Move all your commom JS files to a sub-folder like 'app/assets/javascript/global' then in the application.js, modify the //= require_tree .
line to //= require_tree ./global
.
Now you are free to put your controller-specific JS on the 'app/assets/javascript/' root and they will not be included in compiled JS, being used just when you call them via = javascript_include_tag
on your controller/view.
Though you have several answers here, I think your edit is probably the best bet. A design pattern that we use in our team that we got from Gitlab is the Dispatcher pattern. It does something similar to what you're talking about, however the page name is set in the body tag by rails. For example, in your layout file, just include something like (in HAML):
%body{'data-page' => "#{controller}:#{action}" }
Then only have one closure and a switch statement in your dispatcher.js.coffee
file in your javascripts folder like so:
$ ->
new Dispatcher()
class Dispatcher
constructor: ->
page = $('body').attr('data-page')
switch page
when 'products:index'
new Products()
when 'users:login'
new Login()
All you need to do in the individual files (say products.js.coffee
or login.js.coffee
for example) is enclose them in a class and then globalize that class symbol so you can access it in the dispatcher:
class Products
constructor: ->
#do stuff
@Products = Products
Gitlab has several examples of this that you might want to poke around with in case you're curious :)
You can also group the js in folders and continue to use the asset pipeline to load your javascript selectively depending on the page.