eddorre

Using Rack-Test and RSpec to Test a RESTful API in Rails 2.3.x

August 07, 2011 — 2 Comments

I recently started writing a RESTful API using rack-test for an existing Rails 2.3.11 application, but I noticed the documentation didn’t really go into setting it up for a Rails 2.3 project.

Here are some simple steps to get it going.

In my spec helper file, I wrote the following module:


module ApiHelper
  require 'rack/test'
  include Rack::Test::Methods

  def app
    ActionController::Dispatcher.new
  end
end

Then I can use include the ApiHelper in all of my API specs and write code like:

  
require 'spec_helper'
include ApiHelper

describe 'API Authentication' do
  it "should return json errors with no token" do
    get '/api/tasks.json', :token => ''
    error = { :error => "Token is invalid." }
    last_response.body.should eql(error.to_json)
  end
end    
 

For more examples on building a RESTful API using RSpec, I highly recommend checking out Ryan Bigg’s Ticketee project for his forthcoming Rails book, Rails 3 in Action

Building that Pesky Nokogiri Gem When Using Homebrew

August 22, 2011 — 5 Comments

I’ve encountered the following error (and those like it) many, many times when setting up existing projects that use Nokogiri in conjunction with Homebrew. Every single time I encounter it, I have to sort through my history to try to find out how I solved it.

So this post is as much a reminder to myself as it is to other people experiencing the same issue.

When attempting to install the Nokogiri gem you might get an error similar to this:

  
Installing nokogiri (1.4.4) with native extensions 
/Users/carlos/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/site_ruby/1.8/rubygems/installer.rb:551:in `build_extensions': 
ERROR: Failed to build gem native extension. (Gem::Installer::ExtensionBuildError)

/Users/carlos/.rvm/rubies/ree-1.8.7-2011.03/bin/ruby extconf.rb
checking for libxml/parser.h... yes
checking for libxslt/xslt.h... yes
checking for libexslt/exslt.h... yes
checking for iconv_open() in iconv.h... no
checking for iconv_open() in -liconv... no
 

Here are the instructions that I use to solve the issue:

  
    brew install libxml2
    brew install libiconv
    brew link libiconv
 

Upgrading My MacBook Pro’s Hard Drive to an SSD

January 18, 2011 — 1 Comment

I’ve been intrigued about putting a SSD in my Mac ever since I reading about the performance gains that can come from doing so. This November, the AppleCare in my late 2008 MacBook Pro expired, so I decided to go for it.

I used Fabio Akita’s article, Upgrading My MacBook Pro with an SSD, as baseline to doing my upgrade.

Let’s get started.

Hardware

Intel 160 GB X25-M SSD Drive

I’ve heard good things about OCZ SSD drives and they are considerably less expensive per GB than Intel drives. With that being said, I’ve also heard quite a few bad things about OCZ SSD drives as well; most common is that the drives dies shortly after being purchased (30 days or so). In the end, I decided to go Intel for a few reasons, the first being, I don’t really need a huge hard drive. My original hard drive was 320 GB in size, but I’m only using 90GB of it at the moment (all of my digital media is stored elsewhere). The second reason is the reviews of the drive. Almost all of them were positive with very few negatives. I’ve also bought Intel hardware in the past and have never been disappointed with it.

There was another late contender that I was looking at before I made my decision and that was Crucial’s 256 GB RealSSD C300 Drive. It’s was top-rated by CNet, the reviews that I’ve read are all fairly positive and Crucial has a very good track record with RAM. If I were to do it all over again, I might pick up this drive.

SSD’s are a fairly new technology and things move fast in this space. If you’re considering making the move, then you owe it to yourself to do some research to make sure that there isn’t a better drive for your needs.

Acomdata USB 2.0 SATA Hard Disk Enclosure

I picked this USB hard disk enclosure after reading Fabio’s article. At ~$13, it’s a good drive enclosure with minimal fuss, but I ended up doing the upgrade without it (I just used the Western Digital drive listed below). Unless you have a specific purpose for the hard drive that you’re taking out of your MacBook Pro, then I would suggest getting a drive enclosure so you can reuse it.

Western Digital My Passport Essential 500 GB USB 3.0/2.0 Portable Hard Drive

I picked up this drive to do a clone of the hard drive that was in my MacBook Pro and as a media storage device afterwards.

Software

I chose ShirtPocket’s SuperDuper! for several reasons: 1) Fabio’s article referenced it and he seemed to have no issues, 2) it’s been extensively lauded by John Gruber.

Cloning with SuperDuper! is actually free, so you don’t need to purchase a license, but at ~27 bucks it isn’t that much for the registered version (and you’d be supporting a small Mac development shop). The choice is yours, but I opted to pick up a license.

Cloning your drive is extremely simple, I plugged in my USB hard drive, erased it using the built in Disk Utility and then chose to back up all files from my current hard drive to the USB hard drive. I’m not sure how long this took because I didn’t watch it. I kicked it off and did other things while it was working away. You can probably safely assume that it’s going to take several hours depending on the size of your hard drive and how much data that you have.

Tools

You’ll probably need a couple of screwdrivers for this depending on your MacBook Pro model. For mine, I needed a #00 Phillips Screwdriver and a Torx T6 Screwdriver.

If you don’t already have one, I suggest picking up this Syba 12 Piece set for ~9 bucks. The screwdriver comes with several bits and telescoping shaft.

Installing the Hard Drive

Although the steps are dead simple, it’s probably best to check out some videos on YouTube for your specific MacBook Pro. Here is one that I found for my MacBook Pro:

Restoring your data

Once your hard drive is installed, simply plug in the external USB hard drive and boot up computer. It should boot directly off of the USB drive if all of the steps in the section “Software” were completed correctly. After OS X is booted, open up the Disk Utility application and format the newly installed SSD.This shouldn’t take that long and after the format is complete, open SuperDuper! again and select to copy all files from the USB hard drive to the SSD drive. Restoring the data will probably take the same amount of time it took to backup so keep that in mind.

Once the restore is finished, reboot your Mac and disconnect the USB hard drive. You’ll now be booting off of the SSD. There is one thing that I should note; although SuperDuper! seems to have an option for copying your Spotlight index, it didn’t seem to do that. The first time that the Mac booted up, I noticed that the processes for Spotlight were consuming a high amount of memory and CPU. This was Spotlight re-indexing the entire drive. The time estimation on it was 8 hours but it didn’t take nearly that long (probably no more than 20 minutes).

Final Thoughts

This is probably one of the easiest hardware upgrades I’ve ever done and by far the easiest backup and restore jobs ever. The process itself (excluding backing up and restoring) should take you about 5-10 minutes. After the upgrade here is what I’m noticing:

  • Boot time is greatly decreased (but honestly my computer is rarely shut down all the way and most of the time it’s asleep).
  • Apps open with lightning quick speed.
  • PeepOpen (a text editor file navigation utility) doesn’t stutter on really large projects.
  • Running tests on projects seem to be quicker.
  • It’s now completely silent. I’ve only heard the whirring of the fans when it was re-indexing the drive for Spotlight.
  • It seems to run cooler.

Overall, this is an expensive upgrade, there is no doubt about that. However, if you have the money and want to squeeze all of the performance you can out of your Mac, upgrading is a no brainer.

Introducing Envoy – Deployment Messaging Ruby Gem

January 13, 2011 — 2 Comments

A little while ago, Robby Russell looked up from his monitor and said, “I wish we could get notified in Campfire whenever someone starts and is finishes with a deployment. I think you should write that.” I nodded in agreement and responded, “yeah someday”, and then went back to the client work at hand.

I found myself with some free time on my hands on a weekend and I started working on a gem that would do this for us. A couple of iterations later, some time for user testing and I’m happy to introduce my first Ruby gem titled Envoy.

Using my gem, you can easily send messages to Campfire, Email or a Web hooks url. We’ve been using it for a few months and it’s fit the bill quite nicely.

Here is a sample of how you can use it in your own Capistrano scripts:


begin
  require 'envoy'
  set :envoy_loaded, true
rescue LoadError
  set :envoy_loaded, false
end

if envoy_loaded
  set :messenger, Envoy::Messenger.new
  set :git_username, `git config user.name`.gsub("\n", '')
  messenger.transport :name => :campfire, :account => [YOUR ACCOUNT HERE], :token => [YOUR TOKEN HERE], :use_ssl => true
else
  set :messenger, nil
end

before :deploy do
  if messenger
    messenger.message :name => :start_deployment,
      :subject => "#{git_username} started deployment of branch master to production for project Foo at #{Time.now}"
    messenger.deliver_start_deployment
  end
end

after :deploy do
  if messenger
    messenger.message :name => :end_deployment,
      :subject => "#{git_username} ended deployment of branch master to production for project Foo at #{Time.now}"
    messenger.deliver_end_deployment
  end
end

Rails Ultimate Install Guide on OS X Snow Leopard (using RVM, Homebrew, and Passenger)

April 09, 2011 — 52 Comments

I’ve written numerous guides over the years on installing Ruby on Rails on Snow Leopard. This is an amalgamation of that knowledge and experience. It’s also my last guide that I’ll write for Snow Leopard now that OS X Lion is on the horizon.

Let’s jump right in.

Installing XCode

This whole process breaks down if you don’t install XCode, so we’ll do that now. You can use the XCode that came with your install DVD or download it online.

Installing Homebrew

I used to use MacPorts as my package manager but I’ve recently switched over to using Homebrew. Installing Homebrew is easy since OS X comes with a version of Ruby pre-installed.


ruby -e "$(curl -fsSLk https://gist.github.com/raw/323731/install_homebrew.rb)"

Follow the instructions provided by Homebrew to complete the installation.

Installing Git

Pretty much every Rails hacker out there uses Git, so let’s grab that using Homebrew.


brew install git

Optional Install: wget and oh-my-zsh

The following is completely optional, but I recommend them. By default, OS X uses the bash shell when interacting with the terminal, but that’s not the only shell available. I prefer zsh myself and for my install process, I use Robby Russell’s oh-my-zsh. It’s easiest to install oh-my-zsh with wget, so we’ll install that first.


brew install wget

Once wget is installed, installing oh-my-zsh is easy.


wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | sh

Follow any prompt by the install script to complete installation. Closing and re-opening your terminal should launch zsh from now on. To check run this command:


ps -p $$

You should see zsh instead of bash. If you don’t you can switch your shell manually by running the change shell command.


chsh -s /bin/zsh

Installing RVM

Although OS X comes with a version of Ruby, it’s sorely out of date. We can work around this issue by installing RVM.

If you’ve opted not to install oh-my-zsh, then replace zsh with bash in the command below.


zsh < <(curl -s https://rvm.beginrescueend.com/install/rvm)

Follow any prompts from the RVM install process to complete the installation. One of the final install steps for RVM is automatically loading into a shell session. You should follow the latest install step but for my copy and paste purposes those are:

  
    [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # This loads RVM into a shell session.
 

Close the shell and restart it in order to have RVM loaded.

Installing a Ruby Interpreter

Since I have Rails applications that I work on that still haven’t been migrated to Ruby 1.9.2, I use Ruby Enterprise Edition as my baseline Ruby install.

Install the Readline package

I’ve always installed the Readline package with my Ruby REE install, so let’s do that now.

  
    rvm pkg install readline
 
Optional Install: IConv Package

One of our projects is using the spreadsheet Ruby gem and that requires the IConv RVM package.

  
    rvm pkg install iconv
 
Installing Ruby Enterprise Edition
  
    rvm install ree --enable-shared --with-readline-dir=$HOME/.rvm/usr --patch readline-fix --with-iconv-dir=$rvm_path/usr
 

Obviously, you’ll want to discard the IConv argument if you didn’t install the RVM package. Installing a Ruby interpreter will take a while as it has to download and compile it.

As I said before, I use REE as my base Ruby install so when it’s installed, I’ll set it as my default.

  
    rvm --default use ree
 
Optional Install: Ruby 1.9.2

Although my base Ruby install is REE, I usually use Ruby 1.9.2 for any new Rails 3 applications.

  
    rvm install 1.9.2
 

Installing Database Servers

Although SQLite works for most smaller projects, MySQL and PostgreSQL are usually needed for larger projects. Installing them is easy with Homebrew.

Installing MySQL

  
    brew install mysql
 

Make sure that you follow the instructions at the end to complete the installation and setup. You can review the post install instructions at any time by using the Homebrew info command.

  
    brew info mysql
 

Installing PostgreSQL

  
    brew install postgres
 

Again, make sure that you follow the instructions at the end to complete the installation and setup. As with MySQL, you can review the post install instructions at any time by using the Homebrew info command.

  
    brew info postgres
 

Installing Base Gems

One of the cool things about RVM is that you can create gemsets. These allow you to compartmentalize your Ruby gem installs. By default, RVM creates one global gemset that others will inherit from. In this gemset, I usually apply some base gems that I want across all projects. I also install the Passenger gem at this stage. A full treatise on gemsets is beyond the scope of this guide so I urge you to read the RVM documentation for more information.

  
    gem install bundler
    gem install capistrano
    gem install capistrano-ext
    gem install git_remote_branch
    gem install open_gem
    gem install heroku
    gem install passenger
 

Installing Passenger Apache Module

Before we install Passenger, we have to update the RVM wrapper scripts. I’m not sure why installing a new instance from the Internet doesn’t include everything we need, but Passenger usually complains at the end of the install process if you haven’t done it.

  
    rvm get head && rvm reload && rvm repair all
 

Once that’s completed, finish setting up the module.

  
    passenger-install-apache2-module
 

At the end of the install process, you’ll need to let Apache know that it needs to load the module. I do this by creating a passenger.conf and pasting the code lines from the install instructions.

  
    sudo touch /private/etc/apache2/other/passenger.conf
 

You’ll need to use sudo because that directory is owned by root and you won’t be able to modify it with your account. Open the newly created file with your favorite text editor and paste in the code at the end of the install instructions. Your config file should look something similar to this:

  
    LoadModule passenger_module /Users/carlos/.rvm/gems/ree-1.8.7-2010.02@global/gems/passenger-3.0.1/ext/apache2/mod_passenger.so
    PassengerRoot /Users/carlos/.rvm/gems/ree-1.8.7-2010.02@global/gems/passenger-3.0.1
    PassengerRuby /Users/carlos/.rvm/wrappers/ree-1.8.7-2010.02@global/ruby

    # Set the default environment to development
    RailsEnv development

    # Which directory do you want Apache to be able to look into for projects?
    <Directory "/Users/carlos/work">
      Order allow,deny
      Allow from all
      Options -MultiViews
    </Directory>
 

Installing RubyCocoa and the Passenger Preference Pane

Although it’s quite old, I still use the Passenger Preference Pane for managing Rails and Rack apps. The current version requires RubyCocoa so we’ll need to install that first.

Installing RubyCocoa

  
    cd ~/
    wget http://sourceforge.net/projects/rubycocoa/files/RubyCocoa/1.0.0/RubyCocoa-1.0.0.tar.gz/download
    tar xzf RubyCocoa-1.0.0.tar.gz && rm RubyCocoa-1.0.0.tar.gz && cd RubyCocoa-1.0.0
    ruby install.rb config --build-universal=yes
    ruby install.rb setup
    # have to sudo to install this because the installer wants to copy example stuff out of the /System dir
    sudo ruby install.rb install
    cd ~/
    rm -rf ~/RubyCocoa-1.0.0
 

Once RubyCocoa has been installed, you can download the Passenger Preference Pane.

Optional Install: Pow!!

Recently, 37Signals released a zero-configuration Rack server for Mac OS X called Pow!!. This removes the need for Passenger, RubyCocoa and the Passenger Preference Pane. This project is still very young as of this writing and I haven’t had a chance to try it myself, but if you’re feeling up it, to the installation instructions and the documentation are quite good.

Rails Ultimate Install Guide on OS X Lion (using RVM, Homebrew, and Pow)

July 21, 2011 — 50 Comments

Apple has released their latest version of OS X, Lion, and with that, it’s time for me to update my install guides. I’ve been running the GM Seed of Lion since it was released and I’ve only encountered minor issues along with way with my current Rails development environment.

If you’ve read any of my guides before, you’ll notice that in this guide I’ve switched from using Passenger to using 37Signals’ Pow Rack server. I’ve found that when I upgraded from Snow Leopard, Passenger and Apache stopped serving requests. Both services didn’t have records of requests coming and there were no errors messages recorded. Since trying Pow, I’ve become a convert. It’s dead simple to install and get running.

With that being said, there are some caveats with Pow. First, it hijacks port 80. So if you’re developing other sites using PHP and Apache, there is some extra work for you ahead. Additionally, there is an open and outstanding issue where the server will go haywire and start monopolizing the CPU time. For me, these issues are minor (I just stop the process if it goes haywire – it’ll automatically restart itself) and I don’t develop in PHP.

Now that I’ve gotten that out of the way, let’s dive in shall we?

Installing Xcode

Whether you’re upgrading Snow Leopard or you have a fresh install of Lion ready to go, the first thing that you’ll need to do is install Xcode. It’s free and available at the Mac App Store.

One thing of note, unlike other applications from the Mac App Store, downloading it doesn’t mean installing it. Once downloaded you’ll have to run the Install Xcode application to get it installed.

Installing Homebrew

Homebrew is a package manager that allows you to install all sorts of Open Source goodies on your Mac with a simple command. If you’re upgrading from Snow Leopard and you already had Homebrew installed, my experience has been that you don’t need to do anything different.

If you’re on a fresh install though, you can install Homebrew with the following command.


ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)"

Follow the instructions provided by Homebrew to complete the installation.

Installing Git

Pretty much every Rails hacker out there uses Git, so let’s grab that using Homebrew. Again, if you already had Git installed using Homebrew on Snow Leopard, you won’t need to do anything new here.

  
    brew install git
 

Optional Install: wget and oh-my-zsh

The following is completely optional, but I recommend them. By default, OS X uses the bash shell when interacting with the terminal, but that’s not the only shell available. I prefer zsh myself and for my install process, I use Robby Russell’s oh-my-zsh. It’s easiest to install oh-my-zsh with wget, so we’ll install that first. If you’ve upgraded, you won’t need to do anything new for zsh to continue working.

  
    brew install wget
 

Once wget is installed, installing oh-my-zsh is easy.

  
    wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | sh 
 

Follow any prompt by the install script to complete installation. Closing and re-opening your terminal should launch zsh from now on. To check run this command:

  
    ps -p $$
 

You should see zsh instead of bash. If you don’t, you can switch your shell manually be running the change shell command.

  
    chsh -s /bin/zsh
 

Installing RVM

Although OS X comes with a version of Ruby, it’s somewhat out of date. We can work around the issue by installing RVM.

  
    bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
 

Follow any prompts from the RVM install process to complete the installation. One of the final install steps for RVM is automatically loading into a shell session. You should follow the latest install step but for my copy and paste purposes those are:

  
        [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # This loads RVM into a shell session.
 

Close the shell and restart it in order to have RVM loaded.

NOTE: When I upgraded, I was having an issue with Passenger, and I thought that my RVM install might be the culprit. So I removed RVM completely and simple re-installed it according the these instructions.

If you want to remove RVM complete run the following command:

  
    rvm implode
 

Installing a Ruby Interpreter

Since I have Rails applications that I work on that still haven’t been migrated to Ruby 1.9.2, I use Ruby Enterprise Edition as my baseline Ruby install.

Optional Install: IConv Package

If you use the Nokogiri gem, you’ll probably need this package in order for it to compile.

  
    rvm pkg install iconv
 
Installing Ruby Enterprise Edition

I’m not sure if the CC line is still necessary with the final release of Xcode 4, but with the GM seed and earlier versions of Lion, it wouldn’t work without it.

  
    CC=/usr/bin/gcc-4.2 rvm install ree --enable-shared
 

If you installed the IConv package then the install command is:

  
     CC=/usr/bin/gcc-4.2 rvm install ree --enable-shared --with-iconv-dir=$rvm_path/usr    
 

Installing a Ruby interpreter will take a while as it has to download and compile it.

As I said before, I use REE as my base Ruby install so when it’s installed, I’ll set it as my default.

  
    rvm --default use ree
 
Optional Install: Ruby 1.9.2

Although my base Ruby install is REE. I usually use Ruby 1.9.2 for any new Rails 3 applications. Installing is simple:

  
    rvm install 1.9.2
 

Installing Database Servers

Although SQLite works for most smaller projects, MySQL and PostgreSQL are usually needed for larger projects. Installing them is easy with Homebrew. If you’re upgrading from Snow Leopard, you don’t need to do anything different with your database servers.

Installing MySQL

  
    brew install mysql
 

Make sure that you follow the instructions at the end to complete the installation and setup. You can review the post install instructions at any time by using the Homebrew info command.

  
    brew info mysql
 

Installing PostgreSQL

  
    brew install postgres
 

Again, make sure that you follow the instructions at the end to complete the installation and setup. As with MySQL, you can review the post install instructions at any time by using the Homebrew info command.

  
    brew info postgres
 

Installing Base Gems

One of the cool things about RVM is that you can create gemsets. These allow you to compartmentalize your Ruby gem installs. By default, RVM creates one global gemset that others will inherit from. In this gemset, I usually apply some base gems that I want across all projects. A full treatise on gemsets is beyond the scope of this guide so I urge you to read the RVM documentation for more information.

  
    gem install bundler
    gem install capistrano
    gem install capistrano-ext
    gem install git_remote_branch
    gem install open_gem
    gem install heroku
    gem install powder
 

The powder gem gives you a nice wrapper on some of the Pow commands.

Installing Pow

Installing Pow is simple, just run this command in your terminal and enter your password when prompted.

  
    curl get.pow.cx | sh
 

You can review the install script listed here, if you’re concerned about running command in your shell to automatically install things on your system:

http://get.pow.cx/

All you need to do to get up and running is navigate to your project’s directory in the terminal and run the following command (assuming you installed the powder gem):

  
    powder
 

If the application is a Rails 2.3 application, it’ll prompt you to generate a base config.ru file. For my applications, I just followed the defaults.

Your web application should be available at http://mywebapplication.dev where “mywebapplication” is the name of the directory where your project lives. If there are underscores in the directory name, use hyphens in the URL.

This should be all that you need to get your projects running on the new version of OS X. Happy coding!

Installing REE with rbenv with iconv support and Homebrew

December 28, 2011 — 0 Comments

I picked up a new Mac Mini recently and have been experimenting with rbenv instead of RVM. For some reason, one of my projects was giving me the following error when attempting to start the project (through the Rails console and through pow as well).

  
    ...action_controller/cgi_ext/stdinput.rb:14:in `included': undefined method `alias_method_chain' for CGI:Class (NoMethodError).
 

This error comes up when the Ruby version that you’re using isn’t compiled with iconv support. With rbenv, you can compile iconv support with the following command:

  
    CONFIGURE_OPTS="-c --with-iconv-dir=/usr/local/Cellar/libiconv/1.14" rbenv install ree-1.8.7-2011.03    
 

I should note that I lost quite a bit of time trying to target libiconv with version 1.13. I don’t know if this is a problem with libiconv 1.13 or it was something with my specific version, but once I upgraded to version 1.14, I was able to make it work.