A blog about all things Cloud
Rails and the Warped Asset Pipeline
Published by Risa B on Jul 1 2014
To most Rails developers, just starting or otherwise, the Asset Pipeline is like the magical warp pipe in a certain 8-bit – and its many incarnations – video game most of us grew up with.
And maybe it IS that magical warp pipe that takes us to a whole new world. That’s pretty much what the asset pipeline does. It takes us to a different, and more efficient, world.
If you’re anything like me, you’ll want the TL,DR first. Think of it as finding that one awesome pipe and warping to the last level.
So here is how it works in 3 sentences.
Now that we’ve gotten that out of the way, let’s restart our journey and jump down all the individual pipes to learn more.
THE THREE FEATURES OF THE PIPELINE
That heading might be a bit misleading, as there are other features as part of the pipeline, but there are three main ones: concatenation, compression, and precompilation (of high-level languages). There’s some preprocessing going on!
Once those files have been merged together, they undergo a metamorphosis and are shrunk down to a more manageable size. Extra whitespace and comments are removed. When we code, our CSS files are formatted in a way to make things look pretty and visually appealing. But when you’re a machine, you don’t need comments or pretty indents and spaces. You’re a machine! And all this equates to faster loading times, since it’s less bits being transferred.
Precompilation (of high-level languages)
require_tree, which is just a party with no discernable order to how they are served. This means that if you’ve a file that needs special attention and needs to be loaded first, that should be listed before the
WHAT ABOUT THE OTHER FILES?
All the files that go down the pipeline are given a hash (fingerprint), that allows them to be cache friendly. If that file or it’s fingerprint has been changed, the cached copies along the network will know. Typically this means that all the assets get this crazy gobbledigook at the end of their filename, like so: public/assets/image-1h234j348n45h4u88vjgdfg.png
Don’t worry, you won’t have to actually KNOW the hash at the end. You can still call your files what they are: image.png.
Production environment vs. development environment
With the asset pipeline, the production (prod) environment behaves differently than the development (dev) environment. In prod, Rails has a specific rake task to run asset precompilation, which makes the assets go down the pipeline:
Note: On Ninefold, this task is automatically run during every deployment and redeployment unless you have files in your public/assets folder already – if you do, rake assets:precompile is aborted.
However in dev, assets aren’t precompiled and are served as separate and individual files, based on the manifest order. They are compiled on the fly. Of course nothing’s stopping you from precompiling your assets. In dev, Rails looks at public/assets to see what’s in there. If it’s empty, it goes and checks the app/assets directory for them. This is controlled by config.assets.compile. In development, it’s true by default. In production, it’s false to keep page rendering speedy.
Development: in config/environment/development.rb
config.assets.compile = true
Production: in config/environment/production.rb
config.assets.compile = false
This means that what works locally in dev probably won’t work in prod. It’s always good to double check how things look in prod on your local machine by doing
$ rails s -e production
Simple tip for testing in prod locally
Standard Rails apps come with WEBrick to test things out locally. Naturally, after saying what command to run to test the production environment on your local machine, it would make sense to follow up with some tips on getting things to work correctly. So let’s digress a bit from the asset pipeline to talk about how to really check this out locally.
If you haven’t done so, checkout a new branch, calling it test-prod or whatever you’d like. This isn’t the branch you want to be pushing to production, but it’ll be pretty darn close.
$ git checkout -b test-prod
Now, precompile your assets.
$ RAILS_ENV=production bundle exec rake assets:precompile
At this point you can run
$ rails s -e production, but you’ll notice that none of your assets have been found. All your GET requests for assets will be FATAL.
What happened here? Unlike Apache or Nginx, which can handle serving these assets statically, WEBrick is a pretty dumb web server. You’ve got to tell it what to do. In your config/environment/production.rb file, have this:
config.serve_static_assets = true
Save that and now run
$ rails s -e production. Voila! Your page should be rendering your images and JS/CSS files properly.
CSS and occasional wonkiness
The asset pipeline can be really confusing…mostly when you’re trying to call out images in your CSS. A prime example is when you want a background picture to display, and you call it like this:
It’ll work in dev, but not in prod. If you’ve been paying attention, you can probably figure out why. (Hint, it’s not the ‘assets’ path, though that too is incorrect.)
Luckily for us, we have helpers and tags that make things easier, and those end with -path or -uri, heck even _path and _tag. Of course, there’s reasons behind this, as with anything, but that’s a topic for a different discussion.
Arming ourselves with this knowledge, the background image will work if it’s this:
Alternatively, this also works:
PROTIP for Rails 3.2.x users
If you’re using Rails 3.2, you may want to use turbo-sprockets-rails3. That’ll greatly speed up the sluggish asset precompilation by checking to see which assets were already precompiled and unchanged and only compiling the new / changed assets. This was included in Rails 4 so if you’re running that, no need to worry.
Hopefully you now understand the asset pipeline a bit more. It’s not as warped as it may seem, but it’s definitely a bit confusing. But with this newfound knowledge, you should be fully prepared to dive in and become best friends with the Rails guides on it. Go on and read it! It’s found here
If you’re a Ninefold customer and are confused about how we handle your assets, check out this KB article!
Disclaimer: All images were found via Google image search and probably was modified to fit the blog post. Bonus internet points if you know the references.