Rails

My Dive Into Rails Development

Being new to working in a software development environment, last week was a bit of a crash course in getting together all the pieces. Here are some notes, mostly as a future reference for me but hopefully useful to someone else out there getting started writing software. Everyone seems to use Mac OS X these days so this is a bit skewed towards Macs, but most things apply anywhere.

TextMate

Rails developers love them some TextMate. It's a clean text editor for Mac OS X that mostly stays out of the way and has helpful bundles that do things like auto-completion. If you want to use it for things like git commit messages, add these to your ~/.profile:

export EDITOR="mate -w"
export VISUAL="mate -w"

I'm a Vim person myself, but I've been using TextMate at work to get a feel for the workflow that most people seem to use.

Pig

I played with Pig a bit at SugarCRM, but never on a Mac. It's one of the best ways to ramp up number crunching and file processing. If you want to use it on a Mac, you'll need to set your JAVA_HOME environment variable. I did this by adding the following to my ~/.profile:

export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Home"

Homebrew

It used to be Fink, then DarwinPorts, then MacPorts. Now it seems "Homebrew" is the popular way to get some things up and running that aren't that fun to get up and running on Macs. Example:

brew install mysql

There you go! MySQL is now installed and running. Watch the end of the output for instructions on starting it on boot using launchd, etc. Rails apps tend to use sqlite for development but sometimes you might want to use MySQL.

Ruby Gems

All the functionality you need has probably been written by someone else and stuck in a Ruby Gem. For example:

sudo gem install clarity

Will install a fancy web interface for looking at log files in real time. To prevent all the documentation from being installed on your machine, set up a ~/.gemrc file with the following contents:

gem: --no-ri --no-rdoc

Some people like putting this in /etc/gemrc, but it's always better to put user specific things in your home directory!

It is recommended that you always install gems, including rubygems itself, from source and not from your operating systems package manager. Additionally, once installed everything will probably need to be updated with something like "gem update --system".

RVM

RMV is the Ruby Version Manager. This lets you have multiple versions of Ruby installed side by side, as well as create sets of Gems that can be used in different applications. For example, once set up you can put a ".rvmrc" file anywhere in your directory hierarcy, with contents like "rvm 1.8.7@mygemset". Whenever you cd into this directory, rvm will set up your envrionment to use Ruby 1.8.7 and the "mygemset" gemset, and can update your prompt to remind you what is active. Getting this bit to work requires adding a few things to your ~/.profile:

[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"

export PS1="\$(~/.rvm/bin/rvm-prompt) $PS1"

GIT and Github

Git is the source code management tool of choice for a lot of people. It's fully distributed which enables some interesting workflows, and the Github website has done an awesome job of gluing together lots of pieces that enable effortless collaboration. The Git Reference covers (very well!) most of what you need to know about Git, but here are a few particularily useful things I've found.

Need to delete a remote branch? Delete the branch locally, then push 'nothing' to the remote branch by using the push command and leaving the front of the colon blank. Example:

git push origin :deletedbranch

Need to undo something? 'git revert' doesn't do what you think. Re-checkout the file(s) instead.

To get color in some of the command output, add the following to your ~/.gitconfig:

[color]
        diff = yes
        status = yes
        branch = yes

For auto completion and a more helpful prompt and tab completion of branch names and more, clone a copy of .git_completion.sh into your home folder, and put the following in your ~/.profile:

source ~/.git_completion.sh

function parse_git_dirty {
  [[ $(git status 2> /dev/null | tail -n1) != "nothing to commit (working directory clean)" ]] && echo "*"
}

function parse_git_branch {
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e "s/* \(.*\)/[\1$(parse_git_dirty)]/"
}

export PS1='\h:\W$(__git_ps1 "[\[\e[0;32m\]%s\[\e[0m\]\[\e[0;33m\]$(parse_git_dirty)\[\e[0m\]]")$ '

And read about using "git stash". It is your friend, especially when you forget to create branches to work on different features and ideas, which you _should_ be doing!

Rails

Ah Rails, I wouldn't be here without you. There is plenty of documentation out there on Rails, but a few points of interest:

  • Models are named like "Thing" but in the database the table will be called "things". I'm used to naming my tables "thing" and both case and plurality matter here so thats taken some habit adjusting
  • script/server starts up your rails app in webrick, while script/console sets up your app in an interactive ruby shell that you can use to poke around.
  • If you need to debug something, add breakpoints to your code with "debugger" function calls, start script/server with "-u", and when your app hits the debugger call the script/server will drop you into a debugging session. It works a lot like GDB and is pretty handy for tracking things down.
  • Making a new {anything}? There is probably a generator for that. Running "script/generate" will tell you about all your options
  • "Rake" is "Make" for rails. "rake -T" will list all the available tasks. Looking at how requests are routed? Check out the output of "rake routes".

Rails does a lot of Magic and it can be a bit overwhelming, but overall it's been pretty friendly to me so far. Still need to know more? Watch all of the Railscasts and search the documentation at: http://api.rubyonrails.org/.

Capistrano

Capistrano is the most popular tool at the moment for deploying rails apps. A deploy to a remote server is as simple as "cap deoply" from your development machine, and if you're doing anything more involved than that for new software releases, you're doing it wrong. "cap -T" shows available capistrano tasks. That said, if you're doing more than just deploying a new version of an app...

Chef

Chef is the new Puppet. I used Puppet a lot at SugarCRM, and figured that I need to learn more about Chef so that I can pick the best tool to use, so I've spent some time with Chef over the last week. The "Opscode Platform" is a hosted Chef server that gives you a few things for free without having to set up the whole stack, and I recommend using that for at least your first round of testing. Also worth grabbing into your setup is a copy of Opscode's Chef Cookbooks that are very helpful for setting up pretty common things. Some pages worth reading:

The end result of this tinkering, Add your Amazon EC2 ssh key to your ssh-agent by putting this in your ~/.profile:

ssh-add ~/.ssh/id_knife-test 2> /dev/null

Run a command like:

knife ec2 server create "role[${MYAPP}]" -i ${MYAMI} -G default -x ubuntu -S knife-test

And in a few seconds, MYAPP will be up and running on a new Amazon EC2 instance. Pretty sweet! Assuming of course that you got Chef working and set up a Recipe for your app similar to this one I wrote for deploying ithought.org, recoded as a Rails app, inside of Apache and mod_passenger: https://gist.github.com/aef17730ef8514799dc1.

Thats it for week one!

I've left out a lot, and I have a long way to go, but hopefully some of those snippets will be useful to someone. A few of them took me a little while to figure out and searching the internet for things about "knife" and "make those things stop doing that thing" can be tricky!