Clear the cache from the Rails asset pipeline

Go To StackoverFlow.com

37

I'm starting a new project in Rails, and it looks like the application.js manifest file is doing something funny with the javascripts that I reference - does it cache those files as part of the asset pipeline?

Here's what happened. I added a javascript file named jquery.autoresize.js to the vendor/assets/javascripts folder, and then referenced the file in the application.js manifest like this:

//= require jquery.autoresize.js 

Then I started up the rails server. But after navigating around in my app, I realized that I had accidentally added the wrong version of the jquery.autoresize.js file. So, I deleted that file and then added the correct version to the vendor/assets/javascripts folder. But, to my horror, when I reloaded the page, it is still loading the old javascript file.

I tried emptying my browser cache, then exiting and restarting the Rails server, but to no avail. I hacked a solution together by simply renaming my javascript file and referencing the new name, which worked fine. But there has got to be a better solution to this.

Does the new asset pipeline cache the files you reference somehow? If so, how can I clear that cache? Thanks for any help!

2012-04-04 02:58
by Aaron Gray


52

I'm assuming we're talking about the production environment.

When you change any of your javascripts or stylesheets in the production environment, you need to run rake assets:precompile; this task compiles and compresses the various .js and .css files and creates the application.js and application.css files that is loaded by your views.

It's possible that if you replaced jquery.autoresize.js with a version with an older timestamp, the precompile step might skip it, thinking the compiled version is up-to-date. You can avoid that by running rake assets:clean first, forcing it to rebuild everything in the public/assets directory from scratch.

2012-09-05 23:22
by benzado
Ahh, very interesting, thanks for your thoughts. I was actually doing this on my local development environment, and I never ran rake assets:precompile. So, perhaps that makes it behave differently? Do you think that the development environment would cause it to behave in the way that I described originally - Aaron Gray 2012-09-06 04:03
In the development environment, the hashed filenames are not used, so everything is based on file modification dates. (Do view-source in a browser to see the script links in the HTML header.) My guess is that in the dev environment, the replacement file had an older modification date, and so the browser was just using its cached version. Your edit updated the file's mod time, and that's why the browser finally fetched the new version - benzado 2012-09-06 18:10
Awesome. Thanks for helping me figure this out. I will modify the content of the question and stuff to better explain and give you credit for helping out - Aaron Gray 2012-09-06 19:02
RAILSENV=development bundle exec rake assets:clean, RAILSENV=development bundle exec rake assets:precompile, and RAILS_ENV=development bundle exec rails server is what finally did it for me - Donato 2015-06-20 21:52


31

Also try rake assets:clobber. This will totally reset everything and delete all compiled assets. In addition, I often need to set the environment before pushing to production by going: RAILS_ENV=production rake assets:precompile.

2015-07-20 13:11
by Dex
+1! This solution worked for me. I'm developing a custom asset-pipeline processor and this makes Sprockets enter to the processor again. Th - MegaTux 2017-01-09 15:19
probably the best answe - Anton Semenichenko 2018-04-02 13:49


24

Rails automatically clears the cache for an individual file every time that the contents are edited. To clear the cache for a single file, simply open the file, edit a line of code, and re-save it. Rails will clear the cache for that file, and the browser will load the new file the next time the page is loaded.

The reason jquery.autoresize.js was using the old cached version of the file was because the old version was deleted and then the new version was copied and pasted with the same name into the same folder. Because the file itself was never edited, Rails continued to use the old file that was cached.

This is because the asset pipeline uses fingerprinting for the cache.

Fingerprinting is a technique that makes the name of a file dependent on the contents of the file. When the file contents change, the filename is also changed. For content that is static or infrequently changed, this provides an easy way to tell whether two versions of a file are identical, even across different servers or deployment dates.

When a filename is unique and based on its content, HTTP headers can be set to encourage caches everywhere (whether at CDNs, at ISPs, in networking equipment, or in web browsers) to keep their own copy of the content. When the content is updated, the fingerprint will change. This will cause the remote clients to request a new copy of the content. This is generally known as cache busting.

The technique that Rails uses for fingerprinting is to insert a hash of the content into the name, usually at the end. For example a CSS file global.css could be renamed with an MD5 digest of its contents:

global-908e25f4bf641868d8683022a5b62f54.css

So, if you delete a file you're referencing in the manifest, and then copy in a new file with the same name, the cache busting never occurs. When you edit the file, the fingerprinting kicks in, and a new hash is generated for the file name. This busts the cache for that file.

For the full story, see What is Fingerprinting and Why Should I Care?.

2012-04-04 04:23
by Aaron Gray
I don't think this is correct. The fingerprint is based on the contents of the file. If you delete a file and replace it with a different one with the same name, you'll get a different fingerprint, and a different file name - benzado 2012-09-05 01:18
Thanks for chiming in. Have you tried this in one of your own projects recently? Because I can definitely confirm that when I created this question, the only way I could get the new file to be loaded by my browser was to edit a single line of code and resave it. If it is working for you by simply deleting the file and replacing it with a new one with the same name, I would love to hear about it - Aaron Gray 2012-09-05 22:26
I had a different asset pipeline issue, which is how I came across this question. You say "if you delete a file you're referencing in the manifest, and then copy in a new file with the same name, the cache busting never occurs"; that would only be true if the new/old file had identical contents, in which case who cares which version you have? If you're talking about production mode, you need to run rake assets:precompile to put the files in the public/assets directory; that should be the solution unless you've changed the default config - benzado 2012-09-05 23:15
The steps in bold worked perfectly for me - janko-m 2013-11-14 00:05
Aaron is right, I had the same problem (in dev mode) and tried everything - rake assets:clean, then rake assets:precompile, as well as copying the new file over again and restarting the server. Nothing worked until I opened the new file, added a few dummy words at the end, then deleted them and saved the file. Rails is becoming too complex for it's own good - you know that's the case when simple things require complex steps to get done - abbottjam 2014-02-13 14:33
Unfortunately not even @user906230's solution worked. Rails just continues to serve the old file, I've done everything besides debugging asset pipeline directly. If anybody has solved this please write a comment - Michael 2014-12-09 00:18
@Michael you need to clear you assets cache try running all of the following then recompiiging: Run the following commands: rake assets:clean rake tmp:clear rake tmp:cache:clear rake cache:clear Darwayne 2015-01-16 14:45
rather than editing the file, you can run touch on the file to update the timestamp on it. You can see if this is the issue by running ls -l and checking the modification date - Ian 2015-06-16 21:56
I ran into a similar problem and none of the above solutions helped. We have application.css include a single file (with sprockets' *= require syntax) which then includes further files using compass's @import. Changing files below the @import used to fix things but then after a precompile in dev once it started returning the cached precompiled version. I fixed this by modifying application.css and rerequesting. That busted the cache and now it reloads appropriately - jwadsack 2015-07-03 22:50
Incredible that 4 years later this is still a problem. rake tmp:clear did nothing, I really had to add an empty line to the file to make it work - Jonathan Allard 2016-07-04 21:27


8

rake tmp:clear did the trick for me, I'm using less-rails.

2016-08-10 17:21
by akz92
I have to do this as well to get browserify-rails to update, otherwise it will find and use old files that have since been deleted. rails assets:clean does not work for this - Ryan 2016-12-03 20:05
This command will remove the pid files in tmp directory too - caiguanhao 2017-04-11 01:35


6

I use config.assets.version = '1.01019' in my application.rb to bust the entire cache. When I want to push a complete new version, I increment the version and that does the trick. This takes care of those edge cases where Rails does not recompile as asset for whatever reason.

2015-03-03 21:15
by user3670743
Ads