37

I have a Rails 4 application with

<%= javascript_include_tag "modernizr", "data-turbolinks-track" => true %>

in the head. In development, the following HTML is rendered, and modernizr is loaded:

<script data-turbolinks-track="true" src="/assets/modernizr.js?body=1"></script>

In production, the followign HTML is rendered, and modernizr is not loaded (404 not found):

<script data-turbolinks-track="true" src="/javascripts/modernizr.js"></script>

In production, /assets/modernizr.js is found and browsable.

The Rails documentation says that the javascript_include_tag should generate

<script data-turbolinks-track="true" src="/assets/modernizr.js?body=1"></script>

In production, my stylesheet_link_tags are fine, linking to the /assets/ directory.

Why is the javascript_include_tag linking to /javascripts instead of /assets in production, and how can I fix it?

3
  • 3
    Did you manage to find a solution to this? I'm experiencing exactly the same problem, but none of the answers here help. Commented Sep 29, 2013 at 23:14
  • 2
    in production, you should have a fingerprinted asset-url like /assets/light-0cd9377b97b67182b68c8023bd6c2fbe.css Commented Sep 30, 2013 at 12:19
  • 2
    Is this clean Rails 4 app or an upgrade from earlier Rails version? Commented Oct 3, 2013 at 8:19

5 Answers 5

24
+50

One of the usage statements for AssetUrlHelper indicates it will produce /javascripts/ urls like what you are seeing:

# asset_path "application", type: :javascript # => /javascripts/application.js

(from asset_url_helper.rb line 117 - [1])

This code looks like it can only be reached if the precompiled asset is missing so it would appear that your asset compilation is not working (my deployments usually fail when that happens, so maybe yours isn't even firing).

The same asset_url_helper.rb calls the /javascripts/ part 'extname' and uses the following map to know how to generate the name:

 # Maps asset types to public directory.
  ASSET_PUBLIC_DIRECTORIES = {
    audio:      '/audios',
    font:       '/fonts',
    image:      '/images',
    javascript: '/javascripts',
    stylesheet: '/stylesheets',
    video:      '/videos'
  }

A new Rails 4 app has this in the config/environments/production.rb

  # Do not fallback to assets pipeline if a precompiled asset is missed.
  config.assets.compile = false

which seems to match the behavior you are seeing.

Sign up to request clarification or add additional context in comments.

2 Comments

thank you! Some js/css file not precompiled,cause it can't associated with application.js/css file,so rails 4 assets precompile can't find those files. You can add file to precompile file list as this #config/environments/production.rb config.assets.precompile += [ Proc.new {|path| File.basename(path) =~ /^[^_].*\.\w+$/} ]
Rails seems to have some very bad defaults for the asset pipeline.
12

By default, Rails only precompiles application.js, application.css and any images it finds in the assets path. Therefore, in production mordernizr will not get precompiled and thus the javascript helpers will not be able to find the file.

In order to fix the issue, you can add modernizr to the precompile list by modifying the following config in production.rb

config.assets.precompile += ['modernizr.js']

For more information see the Rails Guides

1 Comment

This answer is correct. In prod, if javascript_include_tag cannot find the precompiled javascript asset in the searching path (which is ./public/assets/ I think), it will generate src starting with /javascripts/ (Rails thinks you will put that assets in ./public/javascripts/). In dev, config.assets.compile is set to true, so if javascript_include_tag cannot find the assets in ./public/assets, rails will compile the assets, then it will find it. In production, config.assets.compile is false. So use config.assets.precompile to make sure your assets are precompiled.
4

Be sure to precompile your assets in production by running this command:

RAILS_ENV=production bundle exec rake assets:precompile

The Rails Guide on the asset pipeline can give you more details: http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets

3 Comments

But this only compiles the assets into the public/assets/ folder - it doesn't explain why the path is being generated incorrectly.
Did you change the path in your production.rb? It would look like config.assets.prefix = "/some_other_path" guides.rubyonrails.org/…
No, I didn't. All my assets in vendor/ get compiled correctly into /assets and the paths are correct. It's just javascripts in /app/assets for some reason have the wrong path generated by javascript_include_tag. And yes, I added them to precompile. Really strange behaviour...
1

I have a new application using Rails 4 deployed on Heroku with :

<%= javascript_include_tag "application", "data-turbolinks-track" => true %>

my javascript application.(fingerprint).js called from the src: assets/application.js

i think your problem come from something into your production.rb who define assets from another location.

So maybe you can add Moderniz.js to

config.assets.precompile = ['.js', '.css', '*.css.erb']

in config/production.rb

Or simply require modernizr script into your application.js

//= require mordernizr

and remove the modernizr script call into your layout.

<%= javascript_include_tag "modernizr", "data-turbolinks-track" => true %>

Can you check from where your application.js is served into your production environment ?

Comments

-1

It may be because this file needs to be in /vendor/assets/javascript instead of /app/assets/javascript. The Vendor folder is for javascript libraries, and the App folder is for your code.

A better solution than adding a tag to your layout would be adding a script reference to your application.js and let the sass compiler compress and attach it to your main javascript file.

If you don't get a definitive answer, check out: http://guides.rubyonrails.org/asset_pipeline.html#asset-organization

1 Comment

The files in both /vendor/assets/javascript/ and /app/assets/javascript/ folders get compiled into the public/assets/ folder, and the generated manifest.json file describes the logical paths to find the fingerprinted files. However, for this to work, the path generated by javascript_include_tag still needs to point to assets/.

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.