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
First: remove \\=require_tree
from application.js
Second: all your JS code must be alocated at /app/assets/javascritpt
and all your CSS code must be alocated at /app/assets/stylesheets
Another option: to create page- or model-specific files, you could create directories inside your assets/javascripts/
folder.
assets/javascripts/global/
assets/javascripts/cupcakes
assets/javascripts/something_else_specific
Your main application.js
manifest file could be configured to load its files from global/
. Specific pages or groups of pages could have their own manifests which load files from their own specific directories. Sprockets will automatically combine the files loaded by application.js
with your page-specific files, which allows this solution to work.
This technique can be used for style_sheets/
as well.
This has been answered and accepted long ago, but I came up with my own solution based on some of these answers and my experience with Rails 3+.
The asset pipeline is sweet. Use it.
First, in your application.js
file, remove //= require_tree.
Then in your application_controller.rb
create a helper method:
helper_method :javascript_include_view_js //Or something similar
def javascript_include_view_js
if FileTest.exists? "app/assets/javascripts/"+params[:controller]+"/"+params[:action]+".js.erb"
return '<script src="/assets/'+params[:controller]+'/'+params[:action]+'.js.erb" type="text/javascript"></script>'
end
end
Then in your application.html.erb
layout file, add your new helper among the existing javascript includes, prefixed with the raw
helper:
<head>
<title>Your Application</title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= raw javascript_include_view_js %>
</head>
Voila, now you can easily create view-specific javascript using the same file structure you use everywhere else in rails. Simply stick your files in app/assets/:namespace/:controller/action.js.erb
!
Hope that helps someone else!
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.js
SITENAME = new Object();
SITENAME.cars = new Object;
SITENAME.users = new Object;
SITENAME.common.init = function (){
// Your js code for all pages here
}
// cars/init.js
SITENAME.cars.init = function (){
// Your js code for the cars controller here
}
// cars/index.js
SITENAME.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.
JavaScripts are only merged when you tell Rails (Sprockets, rather) to merge them.
Here's how to do it especially if you don't have to execute tons of libraries for your specific page, but only to run a few hundreds lines of JS more or less.
Since it's perfectly fine to embed Javascript code into HTML, just create under app/views shared.js directory and place there your page/pages specific code inside my_cool_partial.html.erb
<script type="text/javascript">
<!--
var your_code_goes_here = 0;
function etc() {
...
}
-->
</script>
So now from wherever you want you simply do:
= render :partial => 'shared.js/my_cool_partial'
And that's it, k?