1

I am reading rails guides documentation for asset pipeline. It states that coffeescript page specific generated files are by default ready to user if there is a require_tree directive on the manifest. This is not working with me I have to do include this

<%= javascript_include_tag params[:controller] %>

on the specific controller. What am I missing ?

4 Answers 4

1

The asset pipeline will compress all of your JS into a single file, application.js. In order to call JS for a specific page, you will need to organize your JS by controller and action. There is a gem, RailsScript that does this automatically and it's compatible with Turbolinks which can give you a single page application feel.

RailsScript only takes a few minutes to learn, https://github.com/gemgento/rails_script.

A specific example using rails script:

# app/assets/javascripts/users.js.coffee

window.App ||= {}
class App.Users extends App.Base

   show: ->
      alert('The users#show action!')
Sign up to request clarification or add additional context in comments.

Comments

0

I think you are misunderstanding the asset-pipeline in general. It doesn't load the javascript-files individually, but rather all the .js.coffee files will get compiled into one big js-file, which you have to include in your views/layout like this

    <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>

If you want some js-code that is only available in one view, you definitely should not include that into the asset-pipeline.

Comments

0

Not sure if I've misunderstood your first paragraph, but I think what the line means is that if your application.js manifest contains a line like:

//= require_tree .

Then yes indeed, page specific javascript, or coffeescript will be loaded, not only for that specific page, for for all pages. If you want to constrain assets to certain pages like you've described, you will need a file located in app/assets/javascripts/ with the pluralized name of the controller, and .js.

I would personally create this as another manifest for that specific page, that way I can load multiple assets. Lets say you have a controller called UsersController, with various assets used by that controller's views. What you then need, in order for the line you wrote in your question to work, is a .js filed users.js or users.js.coffee in the app/assets/javascript directory.

Alternatively, to maintain the naming convention, I do something like this:

<%= javascript_include_tag "application-#{params[:controller]}"%>

and then of course name my file appropriate (application-users.js).

Also, when you do this, you'll want to stop your page-specific assets from loading for all controllers. Simply remove the //= require_tree . line and replace it with explicit //= require lines as needed.

6 Comments

@MichaelSzyndel I have something pretty well the same, yes. Did I write something incorrect?
To my knowledge this should not work in production with asset pipeline enabled. Of course you can disable asset pipeline but this is not good solution.
@MichaelSzyndel Oh, no it definitely works in production. This approach that I've described is ultimately no different than the inclusion of the typical application.js manifest in your application.html.erb. Its the same thing on principle. The only difference between this version and mine is that I use an instance variable set up by the controller; I don't use the params[:controller], but that's just semantics. Maybe there's something I'm missing though; what part specifically made you think it would not work?
I am not saying that this is not working, I just thing another approach is a best practice. And to repeat my question - you do not use asset pipeline?
@MichaelSzyndel Yes, this is all done through the asset pipeline, in both development and production; sorry if that was not clear. If you know of a better approach, please let me know; I would be very interesting in knowing about it.
|
0

Here's a way to do page-specific javascript in rails.

  1. Install the jquery-readyselector.js plugin. (It's 18 lines)

    a. Copy the contents of https://raw.github.com/Verba/jquery-readyselector/master/jquery.readyselector.js

    b. Paste the contents to a new file at assets/javascripts/jquery_readyselector.js

    c. Require jquery-readyselector

    // assets/javascripts/application.js 
    //= require jquery_readyselector
    //= require_tree .
    
  2. Create CSS classes so we have a way to reference each page individually.

    <%# views/layouts/application.html.erb %>
    <body class="<%= controller_name %> <%= action_name %>">
    
  3. Now we can scope our javascript to our page using CSS.

    // assets/javascripts/posts.js
    $(".posts.index").ready(function() {
    
    });
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.