Been a while. I’ve been working on other things like my daddy blog and some other nerd side projects here and here.
If you aren’t a) at least a little nerdy and b) interested in Ruby on Rails, stop reading now. You won’t care about this.
I am relatively new to the Rails world (October of 2010) but have plenty of experience with lots of other stacks and just got back last week from RailsConf 2011 in Baltimore. There was a strong focus at the conference on the upcoming Rails 3.1.
So this week at work I started playing with upgrading our Rails app to Rails 3.1.rc1. There isn’t a whole lot of documentation about 3.1 yet as expected, its not even finished, but most of the documentation that I’ve found relates to creating new apps, not upgrading existing apps.
I figured I might share my thoughts and experiences so far because by all accounts, 3.1 introduces lots of great changes.
Again, I’m certainly no expert and I’m almost positive I’ve done some things wrong but as of right now, we pretty much have an upgraded Rails 3.1 app. Go take a look at the official release for the basic info. I will not go into much detail here about actually using CoffeeScript or Sass. Those will be in future posts as I use them more. This is going to be more about “upgrading your infrastructure”.
Arguably the biggest new feature is Asset Pipeline. To take advantage of this, it basically meant manually creating an assets directory in the /project/app directory and then again in the /project/vendor directory. Inside those directories, I created images, javascripts, and stylesheets directories (just like what you had in your public directory. Now for the fun…
We had our share of JavaScript libraries, starting with jQuery. jQuery is now the default JS library so I got rid of our versions as well as rails.js. Then it was time to make choices. Application-specific JS files went into /project/app/assets/javascripts and the additional jQuery libraries went into /project/vendor/asssets/javascripts. The same types of changes for the stylesheets and for images. By this point, we had nothing left in the public directory except for some empty directories.
Nothing will work yet.
Configuration changes to be made in your Gemfile
- Change your gem ‘rails’ to gem ‘rails’, ‘3.1.0.rc1’
- Add the following gems for the Asset Pipeline: ‘sass’, ‘coffee-script’, ‘uglifier’
- Make sure you have the ‘jquery-rails’ gem
- Ran into some problems with dependencies for the omniauth gem and commented it out for the moment
Run the typical bundle install.
In application.rb you need to add:
config.assets.enabled = true # Enables the Asset Pipeline
In development.rb I commented out the config.action_view.debug_rjs = true line. Sometimes you get to a point where you just want to see something work.
To actually reference the assets correctly, a few more changes to go…
We were using application.js as the global JS file. I moved all that JavaScript into a new /project/app/assets/javascripts/project.js. application.js can now be used as the aggregator. At runtime, all of your JS libraries will be collected into this file and. First, in your layouts, or wherever you do your JavaScript includes, you just need this one include:
<%= javascript_include_tag “application” %>
Here’s what our application.js looks like (this is the whole file):
//= require jquery
//= require jquery_ujs
//= require_tree ../../../vendor/assets/javascripts/
//= require “project”
Notice the quotes around “project”. That is similar to the “old” way where it is referencing a file, any file in any of the asset directories, without the extension. Add as many as you like. If you just want to load all the JS files in the directory, you can just do:
//= require .
Keep in mind, if the order that the files are loaded matters, you need to add them manually like the “project” reference.
The key thing to know here is that whatever you list in this file will be loaded on every page so if you have more controller-specific JavaScript libraries, the old-fashioned way still works: Add another <%= javascript_include_tag “other_library” %> to the views you want.
You now need to do some similar stuff for stylesheets. The concept is the same. The syntax is a little different, of course, based on CSS:
/*
*= require_self
*= require “mywidgets”
*= require_tree ../../../vendor/assets/stylesheets/
* require_tree .
*/
You then add your <%= stylesheet_link_tag “application” %> just like for JavaScript.
And you’re ready to go…