How to Play with Rails 3.1, CoffeeScript and All That Jazz Right Now
Maybe I'm weird (actually, there's no maybe about it) but when I first heard about Rails 3.1 getting CoffeeScript and Sass out of the box, I wanted to see how it worked and how smooth the process would be. So like quite a few people on IRC I've seen, I installed edge Rails (currently 3.1.0-beta) and got playing. (Yes, it's PRE-RELEASE. Expect mischief!)
I hit a couple of stumbling blocks on my way so I thought I'd explain what I found to be the smoothest way through to getting to play with the new Rails 3.1 goodies. I'll only take you as far as making some changes and seeing the results, though - you're on your own from there!
Note: This post was written in April 2011. If you are reading much later on, much of this post may no longer be relevant and you should refer to guides about installing the eventual full release of Rails 3.1 instead. If I remember, I'll update this to reflect that ;-)
Installing Edge Rails (Rails 3.1 Beta)
Being a conservative kinda dude with the versions of things I run, I hadn't run the edge Rails gauntlet for some time. I naively tried rails new myapp --edge
and while it appeared to work and installed edge Rails, there be dragons (that even rake rails:update
couldn't slay). So do it this way instead:
- Head to whatever directory you use as the base for all of your git cloning. I'll assume
~/code
from here on out. - Clone the Rails repository from GitHub with:
git clone git://github.com/rails/rails.git
Creating a Bare Rails 3.1 App
Cloning edge Rails was the easy bit. Now let's create an app with the bad boy:
- Head to whatever directory you want to use as the base for your Rails projects. I'll assume you remain in
~/code
. - Create a new Rails app with:
~/code/rails/bin/rails new yourapp --edge
It's important to note that we're explicitly calling the
rails
script that's in the edge Rails git repository we just cloned. And, of course, you can call the app whatever you like but I findyourapp
to be both unique and catchy. - Enjoy watching your Rails app being created and waiting for Bundler to finish its work grabbing edge versions of all sorts of things.
- Dive into your app's folder:
cd yourapp
- Check everything went OK so far by running:
rails server
- Browse to
http://localhost:3000/
(or whatever is relevant in your case) and ensuring you get the usual Rails welcome page. - CTRL+C your way out of
rails server
and get back to the prompt.
We have a working but dead boring Rails 3.1 app on our hands. Let's get something happening and see what Rails 3.1 is rocking in the CoffeeScript and Sass departments.
In the interests of having something running as soon as possible, we'll lean on the scaffold
generator to get some default, core team approved model, controller, and view code up and running. Simply:
rails generate scaffold Link title:string url:string slug:string visits:integer
Yes, it's an example model for a URL shortener (the new "hello world" or "blog in 15 minutes" project)! That doesn't matter though - you can do whatever you like.
Don't forget to run:
rake db:migrate
I did ;-)
Sprockets - Asset Packaging Shenanigans!
Run rails server
again now and browse to http://localhost:3000/links/
- pretty typical scaffolding fare, right?
View the source though and check out the <head>
section:
If you dig into application.js
and application.css
(as they're being served up by the server), you'll notice that they're a bit different to the same files in older Rails apps. They contain JavaScript code and CSS code respectively but if you look through the /public
folder in your app, those files are nowhere to be found. Shenanigans!
Or not. Sprockets is merely at play, melting and merging down multiple CSS and JavaScript files into a single gooey lump to send to your Web browser.
Playing "Hunt The JavaScript and CSS"
We're getting CSS and JavaScript being served up through application.css
and application.js
just fine then, but where are they coming from? Here's a clue!
Oh yes, there's a app/assets
folder and its beautiful children javascripts
and stylesheets
. It seems these two fine specimens will become our friends when we make the transition to Rails 3.1.
You may notice that my file tree doesn't look quite the same as yours. That's because I've already started playing with CoffeeScript and Sass by creating an app/assets/javascripts/awesome.js.coffee
file and a app/assets/stylesheets/scaffold.css.scss
file (the latter just being a rename of the scaffold.css
file you already have).
If you take a sneaky peek into application.css
you'll notice there's not really any CSS in there. Merely a comment with a directive like so:
/* * FIXME: Introduce SCSS & Sprockets *= require_tree . */
require_tree
is just telling the system to bundle together everything from the stylesheets
folder into a single file. Awesome - thanks Sprockets!
Playing with Sass
To have a play with Sass first, rename scaffold.css
to scaffold.css.scss
. If you then reload the /links
page in your Web browser you'll notice little difference. Why? Because Sass (or, more specifically, SCSS) is merely a superset of CSS and any existing CSS will work with it!
Open up scaffold.css.scss
and you'll see it's pretty boring. It's just the standard stuff that comes with Rails after all. The first section looks something like this:
body { background-color: #fff; color: #333; }
Let's say we want to keep our background and text colors in variables so we can use them throughout our CSS later (meaning we only have to change a couple of variables instead of hundreds of references if we want to retheme our app). Rewrite the previous section to:
$background_color: #fee; $text_color: #000; body { background-color: $background_color; color: $text_color; }
Here I've assigned the colors to variables and then use the variables in the CSS. I've made some minor changes to the colors too so that I can definitely see a difference when I reload the page in my browser.
And, well, that's it. That's the absolute bare basics of using SCSS in Rails 3.1. Dead simple. Stick .scss
on the end of a filename to trigger the SCSS/SASS parser and you're cooking with gas.
Playing with CoffeeScript
At the time of writing, the application.js
file is a wee bit broken as it has a comment that's not being parsed out. Since this stuff was only added on the very day I wrote this post, I'll let them off. But in case it's broken for you still, get application.js
looking like this:
#= require jquery #= require jquery_ujs #= require_tree .
These directives should remind you of the equivalent in application.css
. As with there, they include other JavaScript files into application.js
when it's served up. You get jQuery, the "unobstrusive" jQuery helpers for Rails, and any other files in the javascripts
folder (currently none).
To give CoffeeScript a try, create a file called awesome.js.coffee
in the app/assets/javascripts
folder and populate it thus:
square = (x) -> x * x alert square(10)
If you refresh the http://localhost:3000/links/
page again now, you'll have an annoying JavaScript alert window popping up with "100" in it (the result of square(10)
).
This isn't the time or place to dig into what CoffeeScript does or how it works but.. you've just played with it nonetheless ;-) If you want to learn more about it, its official homepage is packed with useful stuff.
Like the street walker I picked up solely to use the car pool lane, I'm going to dump you off at the curb here in the middle of conversation. It's been fun. Good luck and have fun breaking Rails 3.1. If you find any really nasty bugs, be sure to either raise a ticket so the lovely Rails developers can make Rails 3.1 even better or, y'know, submit a patch yourself.
Want to show some appreciation after this lovely blog post? Check out the Ruby Weekly and JavaScript Weekly e-mail newsletters or pass them on to your buddies or co-workers. People are loving them and they're doing great but the more the merrier!
April 14, 2011 at 2:22 am
Good to see what they have planned for Rails 3.1. I recently started using Sprockets 2 in my Rails 3.1.x app. It took a little digging to figure out how to set things up (and my setup is a little different from what it looks like they are going to do in Rails 3) but for those wanting to go ahead and play with this goodness check out the guide I put together on the subject a few days ago.
https://gist.github.com/911003
April 14, 2011 at 3:44 am
Thanks Eric!
April 14, 2011 at 6:57 am
Or if you just want to play with CoffeeScript in your Rails {2,3} application / Sinatra or Rack application, you can also try out barista right now ;)
April 14, 2011 at 1:09 pm
scaffold.css.sass should be scaffold.css.css above. Being new to sass/scss following along with the above caused the Sprockets to complain about syntax..
April 14, 2011 at 1:21 pm
How is Rails 3.1 dealing with the Sass compilation? Is it on-the-fly? Is there a rake task? Is it cached in the production environment?
Same question for sprockets and coffescript.
Another great article Peter!
April 14, 2011 at 1:54 pm
@Patrick: Odd. It works fine for me. Without the "sass" I ended up with non-compiled code. But.. they're tweaking edge Rails all of the time so a lot of what's in here could go "off" quite quickly ;-)
April 14, 2011 at 2:08 pm
Starting with a clean rvm ruby 1.9.2 gemset, I had to install bundler and i18n to get things moving. Just FYI.
April 14, 2011 at 2:28 pm
@peter. Yep all depends on which revision you get I would imagine. But if you look, in the "Playing "Hunt The JavaScript and CSS" section you called it "scaffold.css.scss" and in "Playing with Sass" you called it "scaffold.css.scss". Which is where I think the confusion is coming from. Regardless thanks for the post...
April 14, 2011 at 2:41 pm
bah.. More coffee (and coffeescript needed..) "playing with sass" section file is called "scaffold.css.sass".
April 14, 2011 at 4:26 pm
Just wondering .. we'll write CoffeeScript and then debug JavaScript on Firebug??
April 14, 2011 at 5:47 pm
I had to remove the following comments in application.js to get the coffeescript working:
# FIXME: Tell people that this is a manifest file, real code should go into discrete files
# FIXME: Tell people how Sprockets and CoffeeScript works
#
April 14, 2011 at 6:52 pm
@aaron's complaint was in the right place. You've mixed Sass and SCSS as if they were interchangeable. They are different, incompatible synaxes. SCSS is a superset of CSS and files of that type should end with ".scss". Sass is unlike CSS, so you can't just rename a file from ".css" to ".sass" and expect it to work.
April 14, 2011 at 7:23 pm
Mislav: Thanks. It turns out the mismatch was the other way around. I got the filename wrong rather than the superset assumption. My screenshot shows .css.scss whereas I wrote .css.sass, but meant the former. Thanks to everyone who hinted at this and I've now fixed the filename. (Rather than the stuff about Sass, because SCSS is the new, approved technique ;-))
April 14, 2011 at 9:53 pm
When I run "rails new ..." it complains about i18n :
/rails/activesupport/lib/active_support/i18n.rb:2:in `require': no such file to load -- i18n (LoadError)
so i installed the latest i18n gem (0.5.0) with "gem install i18n" and i still get the error. Any idea what's wrong?
April 15, 2011 at 12:56 am
I got the same error as the above ...no such file to load -- i18n (LoadError)
So I added require 'rubygems' to active_support/i18n.rb
Which allowed me to fire up the new app
Then bundling ...
Updating git://github.com/sstephenson/sprockets.git
error: cannot open FETCH_HEAD: Permission denied
An error has occurred in git when running `git fetch --force --quiet --tags "git://github.com/sstephenson/sprockets.git" refs/heads/*:refs/heads/*`. Cannot complete bundling.
bummed. looks like fun.
April 15, 2011 at 1:01 am
Doh, 'Permission denied', gotta sudo, rookie. Ok, no more spam, cheers.
April 15, 2011 at 3:01 pm
@Peter, @Mislav. Hehe, I wasn't being snarkey, I really liked the article. I want those answers. It totally looks trolley though ;)
April 15, 2011 at 3:17 pm
Why didn't they choose RubyJS? And, I have the same question that Andy has. How will we debug it?
April 16, 2011 at 8:23 am
After you created the links scaffold, you need to do a DB migration:
rake db:migrate
April 16, 2011 at 10:21 am
Great howto, thanks ! I had some trouble though on Ubuntu with an RVM-based ruby environment, so I made a blog post about it, check my website if you're under Ubuntu (TL;DR: needed an alias for "rails", and to install a JS runtime, because Ubuntu don't have any by default).
April 17, 2011 at 4:06 am
Same as Dr. Nic. Had to delete the first three lines of application.js to get awesome.js.coffee working.
April 17, 2011 at 4:49 am
Followed the instructions to the T, and keep getting:
Started GET "/assets/application.js" for 127.0.0.1 at 2011-04-16 21:37:16 -0700
[Sprockets] /application.js building
ExecJS::RuntimeError (TypeError: Cannot call method 'write' of undefined
at /var/folders/MJ/MJVJXVDlH2ua+mbx7TGGv++++TI/-Tmp-/execjs20110416-13726-1pglicv:12:20
at /var/folders/MJ/MJVJXVDlH2ua+mbx7TGGv++++TI/-Tmp-/execjs20110416-13726-1pglicv:26:16
at /var/folders/MJ/MJVJXVDlH2ua+mbx7TGGv++++TI/-Tmp-/execjs20110416-13726-1pglicv:1:121
at Object. (/var/folders/MJ/MJVJXVDlH2ua+mbx7TGGv++++TI/-Tmp-/execjs20110416-13726-1pglicv:1:138)
at [object Object]. (node.js:927:23)
at [object Object].emitSuccess (node.js:259:13)
at [object Object]. (node.js:652:21)
at [object Object].emitSuccess (node.js:259:13)
at node.js:509:29
at node.js:988:9
)
April 17, 2011 at 9:29 am
Scratch my prior comment. I had an old version of Node installed. After upgrade, everything's working as expected.
April 17, 2011 at 11:13 am
Yeah, I did make the point ;-)
At the time of writing, the application.js file is a wee bit broken as it has a comment that's not being parsed out. Since this stuff was only added on the very day I wrote this post, I'll let them off. But in case it's broken for you still, get application.js looking like this:
Also, RubyJS? The thing that hasn't been updated in over 2 years..?
April 17, 2011 at 9:21 pm
Any idea whether Rails 3.1 will support js and css compression (rather than just concatenation) in it's final version?
April 18, 2011 at 12:59 am
@Lars: Thanks! You're right - I've updated it.
April 18, 2011 at 8:43 am
To avoid the aforementioned problems with i18n, I had to cd into the rails directory and use bundle exec:
$ bundle exec bin rails new ../yourapp
April 23, 2011 at 3:49 am
After I installed i18n and bundler it game me the message:
Thor is not available.
If you ran this command from a git checkout of Rails, please make sure thor is installed, and run this command as `ruby /Users/andrewgertig/documents/ruby/rails/bin/rails myappname --edge --dev`
After installing thor I then ran the above command but with the addition of "new" between rails and myappname.
Then it worked smoothly.
April 24, 2011 at 3:05 pm
Instead of installing an edge bundle and then creating a new app from that, we wrote up some instructions on installing edge into a new gemset/bundle and then installing the app on top. Should be pretty foolproof
April 26, 2011 at 4:56 pm
You can also just do
rake install
in the rails repo and get all the 3.1.0beta gems.April 26, 2011 at 4:59 pm
Actually, it's evidently broken, try
rake all:install
May 2, 2011 at 5:29 am
Hey folks, on the HAML front... Haven't you ever seen or played with DRYML? I mean seriously, this eats HAML for breakfast, vomit's it during brunch, it's it again for lunch and then eats ERB for dinner.
If you've not seen it, you seriously owe yourself: http://bit.ly/dryml
This is better than sex on the beach... ;) Yeah, heh, talking about the drink.
May 11, 2011 at 12:13 pm
One way to use Rails 3.1 beta without worrying about messing up your existing install is to use RVM and create a new gemset: `rvm 1.9.2@rails_beta --create`.
Then you can muck about all you want and not have to worry about beta sneaking into production code... as long as you remember to switch back.
Pingback: Trevor Turk — Links for 5-17-11
Pingback: A Rails Developer’s impression of CoffeeScript – Part 2 | Vinsol - Leading Ruby on Rails Development and Consulting Firm in India
June 20, 2011 at 5:12 pm
Why is rails adding more redirection that only results in more places where something can go wrong?
All this stuff has its place, but like REST and Bundler, this crap should be in opt-in plugins, not opt-out.
At some point Rails needs to not break everyone's apps on minor point releases.
DHH has gone off the rails. it seems like anything remotely trendy gets stuffed into rails, bloating the framework, for no other discernible reason other than it is trendy.
DHH is messiah of the cargo cult.
Pingback: Posts, tutoriais e screencasts para RoR devs | Chris B.