Understanding the Rails Asset Pipeline
Ruby on Rails is a full-stack web development framework written in Ruby. For a developer who just began working with Ruby on Rails, a lot of things will feel magical, like instance variables defined in controller accessible by the views. Another such thing is the asset pipeline, but it creates chaos at times, especially when moving things to production. A simple google search would yield a solution at that time, yet it wouldn’t feel complete. This post will give you a better understanding about the Rails asset pipeline so that you won’t feel stuck with it next time.
Rails Asset Pipeline
A Ruby on Rails application at the time of creation is given with two manifest files application.js and application.css. These two files by default contain few lines of meaningful code which are deemed mandatory. Let us have a look at the content of those files and try to figure out what they are for.
* This is a manifest file that’ll be compiled into application.css, which will include all the files
* listed below.
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
* You’re free to add application-wide styles to this file and they’ll appear at the top of the
* compiled file, but it’s generally better to create a new file per style scope.
*= require_tree .
This is the default CSS manifest file, which includes all the mentioned files into a single application.css file. The require keyword here functions same as the require keyword in ruby. It makes a file accessible within the file it is called from. The require keyword looks for the mentioned files in app/assets/ folder first, if not found there it will look in the vendor/assets/ folder.
‘require_self’ and ‘require_tree .’
‘require_self’ loads all the content of that file where it is called from, in our case the application.css into the line where its mentioned. ‘require_tree .’ loads all contents in the same folder where it is referenced into the line where it’s mentioned. If we need to include all the files of a sub folder, use ‘require_tree ./folder_name/’. This is helpful when using plain CSS. But if we want to use SASS/SCSS, to use global variables for colors etc, we need to import the CSS file using SCSS method `@import` rather than `require`.
The order in which assets are searched is as follows:
/[assets included by gems]
To compile all the files and minify them we should run rake assets:precompile. This command initiates a rake task which finds the files mentioned in application.css, if they are written in SCSS/SASS it is compiled to CSS, and then added as a part of the application.css file. This application.css file is linked to each page using stylesheet link tag, a rails view helper. Same happens for application.js.
By default, only application.css and application.js are the manifest files and hence they are precompiled. But we might want to use one or more files as manifest files for different layouts. In that case these files should be added to the precompile array at config/initializers/asset.rb
Rails.application.config.assets.precompile += [‘dashboard.js’, ‘dashboard.css’]
Here, along with application.css and application.js files, dashboard.css and dashboard.js files are considered manifest. So during precompile, these files are also precompiled. After precompilation these newly generated files are placed in the public/assets folder.
This is the third folder where we can find assets in a rails application, but adding assets here directly is not encouraged unless it’s a static asset and doesn’t change at all. Also we won’t be able to reference any files placed under this folder using rails url helpers. Assets are generally precompiled only in production environment. If you wish to precompile assets in local run the rake assets:precompile RAILS_ENV=production in local.
If you take a look at the above file names, they have random 64 characters attached to them. This process is called fingerprinting, which makes the entire filename depend on the content of the file. This technique is really helpful in caching the assets. If the content of the file remains the same, the name of files will also remain the same, hence it can be cached. If the content changes, the name changes and so does the cache.
Sass Asset Url Helpers
Whenever we put some fonts, images in app/assets folder then try to access them from CSS, SCSS files, it will work fine in development. But it most of the time it breaks in production saying resource not found /assets/bg-image.jpg. This happens especially for the fonts packages we include. This is because we would have given something like this for the background-image
In production, it will try to get the image from /images/header_background.jpg. But there will be no files present in public folder named ‘header_background.jpg’ unless we place the file in public directory. We would normally place them in app/assets or vendor/assets. So during precompilation it will be compiled and fingerprint will be added to all the no js/CSS assets. Hence all image files, font files will carry fingerprints in their name and this won’t work.
Files are compiled and added as shown above in the public folder. So to reference this in the CSS, we need to use asset path helpers provided by rails. Instead of ‘url(‘/images/header_backgroung.png’)’ use ‘image-url(‘header_background.png’)’. After precompilation this will be added seen as
I hope this post helped you get a hold about Rails asset pipeline. A better understanding on asset pipeline will help you keep the front-end related code more organized and maintainable. If you wish to explore further about asset pipeline, here is the link for official guide.
Stay tuned for our next article to find out if you have the right data for Sentiment Analysis
Planning to acquire data from the web? We’re here to help. Let us know about your requirements.