How to Determine the Md5 Digest of a Given Asset in the Rails Asset Pipeline

How can I determine the MD5 digest of a given asset in the Rails asset pipeline?

As someone mentioned in the comments, appending a hash to the asset paths is a default part of the asset pipeline.

In production, Rails inserts an MD5 fingerprint into each filename so that the file is cached by the web browser

You can read more about fingerprinting in the asset pipeline here. Rails uses Sprockets to compile assets. The fingerprinting comes as part of Sprockets process.

You can use Sprockets' find_asset method, passing in a logical path to your asset to get a Sprockets::BundledAsset instance. For example

[1] pry(main)> Rails.application.assets.find_asset('application.js')
=> #<Sprockets::BundledAsset:0x3fe368ab8070 pathname="/Users/deefour/Sites/MyApp/app/assets/javascripts/application.js", mtime=2013-02-03 15:33:57 -0500, digest="ab07585c8c7b5329878b1c51ed68831e">

You can call digest_path on this object to get it's MD5 sum appended to the asset.

[1] pry(main)> Rails.application.assets.find_asset('application.js').digest_path
=> "application-ab07585c8c7b5329878b1c51ed68831e.js"

With this knowledge you can easily create a helper to return the digest_path for any asset in your application, and call this helper from within your .js.erb files.

Rails asset pipeline and digest values

Grabbed from rails guides

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

Include rails precompiled asset pipeline .JS with md5 hash in filename in static page? or exclude it from getting a hash in the filename?

You'll find something like this in config/environments/production.rb:

# Precompile additional assets (application.js, application.css, and all
# non-JS/CSS are already added)
# config.assets.precompile += %w( search.js )

You should add any assets you want to be able to link to individually, or additional manifest files, to the config.assets.precompile array.

For example, you could make a maintenance.js manifest file containing:

//= require foo
//= require bar

Add it to config.assets.precompile:

config.assets.precompile += %w( maintenance.js )

And then on your maintenance page:

<%= javascript_link_tag 'maintenance' %>

See the precompiling assets section in the asset pipeline guide for more information.

Rails compiles assets both with and without md5 hash, why?

The reason it does it is so that you can access the files without knowing the MD5 fingerprint (for example in a non-rails application, or a file within the rails app which isn't compiled or run by the rails stack (e.g. a 500/502 status error page). In this case you would have to compile the assets then change the css/js links in the static HTML files each time you updated the code (thus causing a change in the MD5 hash).

So instead rails produces 2 copies of each asset file, one with the fingerprint in the filename, the other without (e.g. application-731bc240b0e8dbe7f2e6783811d2151a.css, and application.css). The fingerprinted version is obviously preferred (see 'what is fingerprinting and why should I care' in the rails asset pipeline guide). But the non-digested version is there as a fallback.

As a final thought on the matter I'd take a read of the following pull request to the rails git repo: https://github.com/rails/rails/pull/5379 where they are discussing the pros and cons of the non-digested filenames, and the possibility of being able to turn off compilation of them.

HTH

How does finger print digest gets calculated in Rails 4.2

This is true for Rails 4.2.x not sure about other versions

There are three parts (concatenated in the same order) involved in generating an md5 against a file.

  1. Sprockets::VERSION.
  2. Rails.application.assets.version that is generated here (https://github.com/rails/sprockets-rails/blob/2.x/lib/sprockets/railtie.rb#L91).
  3. Compiled file content.

The actual digest calculation in sprockets 2.x (for bundled assets) is being done here BundledAsset#L30

How to get asset version string from the asset pipeline

I would pass it in the json from the server.

To actually get the fingerprint, you can call digest_path on an asset to get it's MD5 sum appended value. See this SO answer, which the following snippet is taken from:

[1] pry(main)> Rails.application.assets.find_asset('application.js').digest_path
=> "application-ab07585c8c7b5329878b1c51ed68831e.js"

URI mismatch Rails generates MD5 digest in asset URL in production, but controller GET's a non-MD5 URL

Try to use plain html element declaration as follows:

<video width="640" height="500" control="controls">
<source src="../../../public/videos/car_circle.mp4" type="video/mp4">
</video>

Even .erb file will still accept plain html declaration that should be free from any Rails' alteration.



Related Topics



Leave a reply



Submit