As you may have seen from many of my past blog posts, I’m a big fan of Ruby. I’ve been a web developer for a long time now, but for the most part I’ve been working solely within the Microsoft .NET world. Over the past few years I’ve been working with ASP.NET MVC heavily for my day to day work, and I love ASP.NET MVC. It is a great framework. However I’ve had my eye on Rails for a long long time, and I even spent a solid chunk of time a few years ago going through “Agile Web Development with Rails” (that is an updated Rails 3 version), but never got into the world of Rails development since my day to day job was on the .NET stack.
Ever since then I’ve been itching to wade back into those waters. Over the past few months I’ve been doing just that, trying to spend some of my free time delving deeper into Rails 3 than I have with any other version. I didn’t want to just slap together a Rails app and say “Done!”, I really wanted to understand the ecosystem and the day-to-day tools that a “real” Rails developer would be using.
Coming into an already mature ecosystem can be a daunting task. Usually the hardest part of it all is trying to filter out the chaff so that you can get to the wheat. If you aren’t familiar with a development ecosystem, you don’t have a good sense for what is needed and what isn’t. You can quickly become overloaded with the minutiae and fail to learn anything. It requires someone with knowledge and time to wade through it and provide you with some guidance.
The problem is, most of the experienced people aren’t interested in blogging about the beginner stuff anymore, they’ve been doing all of this for years, they want to get to the new features and the more advanced stuff that is useful and interesting to them. I hope to help remedy that a little bit with this series.
Over the last few weeks I’ve been digging into Rails 3 in the hopes of getting a grasp on the tools and environment. I’ve avoided blogging about it up until now, but mostly because I didn’t feel like I could be a respective voice on the topic. I’ve had a number of people encourage me to suck it up and just put something out there. So here it goes…
I want to be upfront that I am doing all of my Rails development on OS-X. As time goes by it seems to be getting easier and easier to do Rails development on Windows, but the premier development environment is still on OS-X. If you are using Windows, I would encourage you to leave feedback (or do a blog post!) on what did and did not work for you. With the exception of a few tools, everything should work just fine on Windows. There is also a great question on StackOverflow that is asking about Ruby/Rails limitations on Windows.
I’m not going to start this post the same way most other beginner posts start, with a sales pitch on Rails or an explanation of MVC. I’m going to assume that you already know why you would want to use Rails, and that you understand the basics of MVC. If not, then there are quite a few good tutorials out there and resources out there.
If you want a really in-depth introduction to Rails 3, two of the best books I have seen out there are The Rails 3 Way by Obie Fernandez and Ruby On Rails 3 Tutorial by Michael Hartl. I am also liking Rails 3 In Action by Yehuda Katz and Ryan Bigg, but currently it is only in early release. And last, but certainly not least, Rob Conery does an amazing job on his Rails 3 screencast series over on TekPub.
If you’re on OS-X the first thing you’ll want to do is to get the developer tools installed. This can be done from the OS-X disk, from the App Store (by getting XCode 4), or you can download it from the Apple Developer center if you’re signed up as a Mac or iOS developer. This will install most of the default tools you need to get started. These are things like Git, Ruby, Ruby Gems, etc…
At this point it might not be a bad idea to run this command in Terminal:
gem update --system
This will just make sure that you are running on the latest version of RubyGems (more on that later).
The second step is to go grab and install RVM (Ruby Version Manager). Ruby Version Manager is exactly what it sounds like, it lets you install multiple versions of Ruby and also multiple sets of gems. This might not mean much to you right now, but it will, and you’ll be thanking some deity later on that you have it. Trust me, you want to do this now.
The first thing you’ll do is run this command:
bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
It is a bit obtuse, but all it is doing is downloading and executing a script which will install RVM for you. If you want to look at the script, just execute the part inside of the parentheses and it will download and display the script in the terminal.
Once that completes, you just need to follow one more basic step to get RVM working, and that is to add a little chunk of code to your bash profile. In many places, including the RVM site, it says to add this code into your “.bash-profile” or “.bashrc” file in your home folder. Well, on my Snow Leopard machine it is just called “.profile” and let’s look at how we can add code into it.
In case you aren’t bash saavy, you can just change directories to a tilde to get to your home directory easily.
In order to see your hidden files (file prepended with a period), just run this command:
On OS-X, if you only have default tools installed, just run this to edit your profile in TextEdit. (Or if you have TextMate run ‘mate .profile’, or Vi run ‘vi .profile’ etc…):
Now you can just paste in this line at the end of your profile:
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # This loads RVM into a shell session.
This will allows RVM to load into your session, if you’re wondering why this is needed you are about to find out. If you run into any troubles, just head over to the RVM installation page and check it out, they have some troubleshooting tips.
Now that RVM is installed, close your terminal and restart it. This should allow RVM to load itself into your session. Go ahead and run the following command to make sure that everything was successful:
It should print some notes out for your platform. The next thing we can do is ask RVM what versions of Ruby it knows about:
rvm list known
You should now see a list of Ruby versions that RVM knows about. In order to install a version of MRI (the original Ruby runtime), you can just specify a version:
rvm install 1.9.2
The code above installs the latest release of Ruby 1.9.2 (at time of writing is 1.9.2-p180), but if you want to install Ruby 1.8.6, just replace the version number. If you don’t know which version you want, then you probably want 1.9.2. You can also set 1.9.2 as the default by running this command:
rvm --default use 1.9.2
And since RVM is all about being able to run multiple rubies, you can install as many as you want!
You should have RVM all installed and setup now. You might be thinking, what the hell was all that about? Well, you’ll find out in a bit.
Due to some comments below, I realized that I made a bad assumption about how RVM works. So the following part has been slightly rewritten, thanks Scott!
Creating the Application
I’m going to call this site ‘rails-baby’. Put it in your home directory wherever you want, I usually put mine in a “Dev” folder under my Documents or something. But the first thing we need to do is to create a gemset for our application. We can do this by running the command:
rvm use 1.9.2@rails-baby –-create
In order to get started, we need to get the latest version of Rails on your machine (3.0.5 at time of writing). I’m not going to explain the command below just yet (we will talk about gems in a bit), but suffice to say it will install Rails into your gemset for you:
gem install rails
This will take a bit. Now that you have Rails installed in your gemset, we need to create a new application.
So once I’m in my “Dev” folder, I’ll run:
rails new rails-baby
This command creates the folder and writes a bunch of stuff into it. You now have a real working Rails app. As I was saying before, we will now get RVM hooked up into our app. So I just go into the directory we just created:
Now that I am in that directory I am going to create what is called an rvmrc file. This file is where the magic of RVM comes in, since we are in our project directory, we can run this command:
rvm use 1.9.2@rails-baby --rvmrc
And this is going to create a file called “.rvmrc” and place the string “rvm 1.9.2@rails-baby” into it. The command in the files tells rvm to use Rails 1.9.2 and to use the gemset called “rails-baby”.
Gemsets, Your Wonderful Friends
What is a gemset? Well, I’m glad you asked. A gemset is just a set of gems. What is a gem? Well, there is a tool called RubyGems which allows you to download and install “gems”. Gems are just projects packaged up in a way that allows you to easily download and install them. The problem is that RubyGems operates in a global way. If I go to a command prompt and type “gem install mygem” then it will install “mygem” into my local RubyGems directory, and then any Rails application I am using can access it. Similar to how we installed Rails earlier.
This sounds great at first, until you realize that this is pretty hard to manage. You might have multiple gem versions in different projects. Or one project might have a gem that needs a specific version of another gem. Or you might have a gem that works on one version of Ruby, but not another. The list goes on and on. Wouldn’t it be great if we could have gems, but specific to each project? Yes, that would be great, and that is exactly what RVM does!
Let RVM Do Its Magic
Now that we have created the .rvmrc file, change directory into the current directory to get RVM to pick up the file by running this command:
You should get a warning that RVM has picked up a new .rvmrc file and asks if you want to trust it. You’ll have to tell it “yes” or “no”, but in this case, we just created this file and so you want to trust it. As the warning states, whenever you cd into this directory, RVM will execute this file which will change your current version of Ruby and your current gemset. Pretty sweet!
Make sure that your gemset is selected by running:
rvm gemset list
If there isn’t an arrow next to your gemset, then just change directories to the current directory again, or cd directories up one level “..” and then back into the rails-baby directory. This will cause RVM to make the gemset active.
You could theoretically just install gems into it now using “gem install whatever”, but you don’t really want to do that just yet. In Rails 3, it is convention to use a tool called Bundler. Bundler allows you to easily track and version the gems which are required by a particular project. Think of RVM as the peanut butter, and Bundler as the jelly. They are both much better when used together.
In order to use Bundler, we will need a Gemfile to put all of our dependencies into. Thankfully Rails 3 creates one for us when we create a new application. The file is called “Gemfile” and is in the root of the application. If you are using TextMate (like me, since I am lame and don’t use Vim), you can just open the entire project folder from the GUI (or by running “mate .” while inside your project folder). Rails is entirely folder based, so there isn’t a project file to open or anything.
Inside of the Gemfile you will see a bunch lines that looks like “gem ‘rails’, ‘3.0.5’” and others that are commented out. The lines in this file tell Bundler what gems to install. And if you are using RVM, then the gems get installed into your project’s gemset! Pretty awesome, huh? Yep, but first we have to get Bundler in order to run our Gemfile. So we just do this:
gem install bundler
You can avoid having to do this by adding bundler to your global gems within RVM by adding it to the ~/.rvm/gemsets/global.gems file. Now that we have bundler installed, we have to tell it to install the gems in our Gemfile. To do this we just run this command:
You’ll get used to running this command pretty often (you can just shorten it to ‘bundle’ if you don’t want to type ‘install’), because anytime you add a dependency to your application, you just add it to your Gemfile and run “bundle install” to install it.
Bundler works in some really cool ways, and does some neat stuff in order to make sure that your library versions don’t change when moving between machines and environments. If you are interested in reading about how Bundler works with lock files, versions, groups, etc…, I would recommend heading over to the “Understanding Bundler” page on the Bundler website.
You’re Almost There
At this point you are almost ready to really get started. You have installed RVM, Ruby, Bundler, Rails, and you have created your first project. Phew! That sure was a lot of work! The next time you do it though, it’ll take you about 1 minute and you’ll just breeze right through it. It really will become second nature.
At this point though, I don’t want to end this post without you having seen your working website! All you have to do is run the command:
And then open your browser to http://localhost:3000. You’ll see the default “Welcome aboard” page in your browser, and you can be proud that you are now running a Rails application! You can also shorten the command to just “rails s”. If you want to see all of the commands that rails provides to you, just run the “rails” command when inside of a Rails application folder.
Before I leave you though, I want you to go into your application and look in the “public” folder and find index.html. This is the static page that you were seeing when you opened your browser, Rails just feeds this page up by default. Don’t you feel cheated? Well, if you don’t, you should! Delete this file out, and then reload your app. Now you’ll see an error that says “Routing Error – No route matches ‘/'”… now you’re really running a Rails app!
In The Future
Now that we have a Rails app setup, the next step for us is to start to add some dependencies and some additional functionality to it. We will look at how to get our routes working, so you can get rid of that nasty error, and we will look at getting some tests up and running. Then after that we will just continue to add functionality to the application, pulling in what we need as we go.
And what I need from you, dear reader, is feedback. Am I missing pieces? Am I doing things in a silly way? Am I the best thing since sliced bread and you just want to shrink me down and put me in your pocket? Let me know!