Updated

In my latest project the need of page specific javascript had emerged. I couldn’t find a solution to make me happy. Thus after some trial and error, I ended up with my way to serve page (view) specific javascript.

Solution

The proposed solution uses content_for to inject page specific javascript in the main application layout, while it organizes all js files inside the views folder, like the diagran shown below.

|-- app
|   |-- controllers
|   |-- models
|   |-- views
|       `-- tasks
|           `-- js
|               |-- edit.erb.js
|               |-- show.erb.js
|               |-- new.erb.js
|            _form.erb.html
|            edit.erb.html
|            show.erb.html
|            new.erb.html
|-- config
|-- lib
|-- spec
`-- vendor

Include the per-view Javascript in a content_for :page_js block and then yield to that block in your application layout. For example

# app/views/tasks/edit.html.erb
<% content_for :page_js do %>
  <script type="text/javascript">
     <%= render file: "#{Rails.root}/app/views/tasks/js/edit.erb.js" %>
  </script>
<% end %>

Then add the page specific javascript in app/views/tasks/js/edit.erb.js

// app/views/tasks/js/edit.erb.js
$(document).ready(function (){
...
 Javascript code here
...
});

Finally add the yield in the main layout file

<!-- app/views/layouts/application.html.erb -->
<!DOCTYPE html>
<html>
  <head>
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
    <%= csrf_meta_tags %>
  </head>
  <body>
    <%= render 'layouts/messages' %>
    <%= yield %>

    <%= yield :page_js %>
  </body>
</html>

The code above injects the javascript uncompressed which is good during development. To speed up your site you should compress it in production.

Add uglifier gem in your Gemfile

gem 'uglifier'

Then modify the code in app/views/tasks/edit.html.erb

<% content_for :page_js do %>
  <script type="text/javascript">
     <%= raw Uglifier.new.compile(render file: "#{Rails.root}/app/views/tasks/js/edit.erb.js)" %>
  </script>
<% end %>

Now javascript is served compressed and you are another happy developer ;)