I recently upgraded a Rails 4.1 app to 4.2. When I look at the page source in development mode, all of the assets now have a fingerprint associated with them:
/assets/application-7d90cdd9d3a3cc2a3445c0e8b748db14.js?body=1
Pre 4.2 I think it used to be
/assets/application.js?body=1
Has something changed or did I miss a config setting?
Yes, Rails 4.2 now enables asset digests ("fingerprints") in development by default.
Here is the commit:
https://github.com/rails/rails/commit/f369bcf9a0dba0a945ca6fe53343c042f54c1fcf
Why the change? It is a long story, but my understanding is that the Rails team wants development and production behavior to be more similar in order to prevent unexpected errors when deploying.
Another related change in Rails 4 is that it no longer generates assets without digests in production. In order to catch mistakes earlier (i.e. before you deploy to production), the development settings have been changed to match the production digest behavior.
To see why this helps, here is an example:
Suppose your code (or a jQuery plugin you're using, let's say) references an asset directly by its path, like this: /assets/logo.png. Before Rails 4.2, this would work perfectly fine in development. But when you deploy, surprise! /assets/logo.png doesn't exist. In order for it to work in production, you would need to use the asset_path helper to generate the correct path with the fingerprint.
By forcing you to use digests/fingerprints in development, Rails 4.2 helps surface this mistake while you are still in development. No more unpleasant surprises at deploy time.
That said, these changes are... controversial, to say the least.
I've discovered this gem: https://github.com/alexspeller/non-stupid-digest-assets
it disables the digests.
From the readme:
Just put it in your Gemfile
gem "non-stupid-digest-assets"
If you want to whitelist non-digest assets for only certain files, you can configure a whitelist like this:
# config/initializers/non_digest_assets.rb
NonStupidDigestAssets.whitelist += [/tinymce\/.*/, "image.png"]
Be sure to give either a regex that will match the right assets or the logical path of the asset in question.
Note that the logical path is what you would provide to asset_url, so for an image at RAILS_ROOT/assets/images/foo.png the logical path is foo.png
Related
I am trying to deploy my Rails 3.2 app to a subdirectory, /support, on an Apache server. Consulting the various posts, the only solutions that seem to have helped involve setting up a symbolic link on the server and changing css image references slightly (two dots '..' required before /assets in the css url references--I can't seem to find the post on that one now). I am getting success in deployment to production with Capistrano, but then strangely after awhile something changes, the /support reference breaks and the stylesheets don't load. Any suggestions?
oh no, please don't deploy rails as sub-uri in that way, you are making yourself in trouble.
So far as I see, ( according to this post: http://kb.site5.com/ruby-on-rails/how-to-deploy-a-rails-3-application-to-a-sub-directory/ ) you created soft links, modified your routes.rb, and changed RAILS.root in environment.rb, and also changed your assets files... all of these make your rails app messed up.
I suggest you use 'passenger' as rails server and checkout this post: http://www.modrails.com/documentation/Users%20guide%20Nginx.html#deploying_rack_to_sub_uri, it's quite easier and simplier
I am moving a rails app to Heroku.
Heroku doesn't seem to support page caching.
So I generated cached pages on my development machine and checked them in to Heroku.
For example, /about_us generates public/about_us.html.
But when I call /about_us, public/about_us.html doesn't seem to be called.
Should my trick work?
Thanks.
Sam
In Rails 3, you'll be using the assets pipeline, so your assets--about_us.html--will be precompiled and put into a folder, WITHIN your public folder. Usually, this file will not be located at 'public/about_us.html'.
With your assets now precompiled, they'll be statically available and appended with an id, that will uniquely identify this asset until it is changed. With the unique signature, caching will occur on both Heroku's (last I checked) as well as within browsers.
Basically, the asset pipeline is doing this already for you.
Everything works great in Development. And app deploys as normal with Capistrano. Assets (javascript & css) appear to be fully pre-compiled and each, along with images, are given a "fingerprint". Problem is when using image_tag("image-name.png") in my view the html it creates in production doesn't include the 'fingerprint'.
The rendered HTML we get in production:
<img alt="Image-name" src="/assets/image-name.png" />
instead of, what I would expect, should be:
<img alt="Image-name" src="/assets/image-name-b89cae2830c2901f844c353b3f3942fe.png" />
So which of Rails 3.1's myriad config options did we botch?
Edit
The troublesome images appear to be those included in a 3rd-party Colorbox image viewing tool we use. Rails 3.1 is fingerprinting its assets (border.png, etc.) but, clearly, the source code for this javascript library doesn't use helpers like image_tag. So in production it is still looking for images named /assets/colorbox/border.png. Currently images are in /vendor/assets/images and work fine in Development. Is there a way to prevent just these images from being "fingerprinted"?
Well, here's how I hacked the 3rd-party files to make things work:
The offending images were in files like vendor/assets/stylesheets/colorbox.css. I first changed the extension of the files to .scss then I changed each url(colorbox/image.png) to image_url("color box/image.png") and now everything is peachy. Assets are served normally in development and fingerprinted in production.
Still like to see the "proper" way to add 3rd-party (vendor) javascript libraries & css to a Rails 3.1 app. Rails team must have anticipate a drop-in solution that doesn't require editing?!? So, please, feel free to offer up other solutions.
Aside: where I previously had manually configured my Capistrano recipe with:
run "cd #{release_path}; RAILS_ENV=production bundle exec rake assets:precompile"
…and its accompanying after deploy:update_code …. I have now removed those lines and instead added load 'deploy/assets to my Capfile. I don't think this makes any difference in the above problem but I wanted to document it anyway as adding your own recipe for pipeline precompiling is no longer necessary in Capistrano 2.8 as it was in the 3.1rc days.
I just upgraded my project to rails 3.1 since I saw the sass feature and the moving of public folder files to the assets folder and considered these major changes I should adjust to, especially the sass feature which is pretty cool.
however, when looking at heroku, i came across this post detailing what to do to get rails 3.1 working on heroku: http://devcenter.heroku.com/articles/rails31_heroku_cedar#getting_started
my app hasn't launched yet but I do intend to be on heroku and from the looks of that document, getting rails 3.1 to run on heroku sounds a little messy, where the assets folder is being created in the public folder.. when it has its own place now in 3.1.
what are everyone else's thoughts on this? i like to keep my code clean and am thinking if I should go back to rails 3.0.
maybe I missed something or a useful reason for doing this here, or am not interpreting this right, because this public folder precompile thing sounds so redundant to me.
In short, is having Rails 3.1 on Heroku good? Or should I go back to Rails 3.0
The asset pipeline is not required, and you can simply not use it if you don't want to.
Definitely keep Rails 3.1 for your app. You will have a much easier time upgrading for things you like in the future, and will have better security updates as the older versions eventually won't be maintained.
I'd recommend using the asset pipeline, and you can read more about it in the guide. http://guides.rubyonrails.org/asset_pipeline.html
If you don't want to use it though in your config/application.rb file change:
config.assets.enabled = true
to
config.assets.enabled = false
You'll probably also want to remove the assets gem group from your Gemfile as well.
Having your assets compiled into public is nothing to worry about. This is a sensible idea as you don't want to have to recompile your assets for every request.
Rails 3.1 has a number of advantages, however ultimately it's your decision, but I certainly wouldn't be fretting about asset compilation.
If youre app if using Jquery-UI (jquery being the new default in 3.1) then for sure just disable the asset pipeline and use 3.1. asset pipeline breaks jquery-ui anyway.
I'm currently wrestling with a lot of all.js / all.css missing hits on a rails 2 upgraded to 3 app on Heroku. I'd prefer not to have a dozen or so stylesheet links per request, and also don't want to statically bundle -> s3 the files as part of the deploy.
This seems like a familiar problem, preparing some content specific to a url and sending it back to the browser.
Rather than using an external bundling app as part of a deploy script etc, has anyone considered having rails generate these files on-the-fly and use varnish to cache them (since it's cleared on redeploy, which is when the css/js files would change)?
My question is whether this has been done already & I just failed to google it, or if it sounds like a dumb idea, why?
Even better: Rails 3.1 asset pipeline does exactly this, and Heroku handles precompilation and caching for you.