Recent Posts

Installing Ruby on Rails, Passenger, PostgreSQL, MySQL, Oh My Zsh on Snow Leopard, Fourth Edition

February 08, 2010

Welcome to what seems like my tenth installment (actually, it’s the fourth) of showing you how I setup my development environment on a fresh OSX install. In this case, I’m actually getting a MacBook setup for a new employee with Snow Leopard.

Over the years, I’ve evolved these following steps and they’ve helped our team maintain a consistent and stable envirnment for Ruby on Rails development. I know that there are a few other ways to approaching this and I’m sure you’ll get similar results, but this approach has allowed me to maintain a hassle-free setup for the last five years.

As with all things… your milage may vary.

Phase One

During this initial phase, we’re going to install the primary dependencies and setup our environment.

XCode

The first thing that you’ll need to do is install XCode, which almost everything depends upon as this will install developer-friendly tools for you. Apple has been kind enough to ship this on your Snow Leopard DVD.

Go ahead and install XCode from the Optional Installs folder.

(might require a reboot)

You can also download it online.

MacPorts

Now we’ll install MacPorts, which the web site describes itself as, “an open-source community initiative to design an easy-to-use system for compiling, installing, and upgrading either command-line, X11 or Aqua based open-source software on the Mac OS X operating system.”

As I’ve said in past versions of this guide, this tool is about to become one of the most important tools on your operating system. It’ll be used time and time again to maintain your libraries and many of the Unix tools that you’ll be using. If you’re from the Linux or BSD world, you are likely familiar with similar tools… such as: apt-get, port, and yum.

You’ll want to download the latest stable version from http://www.macports.org/. Once downloaded, you can install it.

Once this is installed, you’ll be able to use the port command from your console.

Wget

Let’s test out your MacPorts install by installing a useful tool called wget, which we’ll use to install oh-my-zsh.

sudo port install wget
```bash
### Git and Subversion

Every development environment should have some source code management
tools available. We'll install both of these with one command.
```bash
sudo port install git-core +svn
```ruby
This will install git and subversion.

### oh-my-zsh

[Oh My Zsh](http://github.com/robbyrussell/oh-my-zsh) is the most
amazing thing to happen to shells since... well since I said so. It's
one of my open source projects that I encourage you to give a whirl.
```bash
wget http://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | sh
```ruby
That's it. The next time you open up your terminal, you'll be running
zsh with a bunch of stuff available. For more information, visit
<http://github.com/robbyrussell/oh-my-zsh>.

### Terminal theme (optional)

I never understood why the icon for Terminal has a black background but
when you start it up the default theme is black on white.

![](http://img.skitch.com/20100208-1b92cbx8gtuttqsbdd49qspq7f.jpg)

versus

![](http://img.skitch.com/20100208-8dnmpswyumfk73h942g6u4fih4.jpg)

Anyhow, I'm a fan of the the dark background. To change this, open up
preferences in Terminal. Select **Pro**, then click on the **Default**
window so that this sticks around.

![](http://img.skitch.com/20100208-mr4q4y5btq7sscuh7ceky3ahgx.jpg)

Let's now open up a new Terminal window..

You should be looking at something like this:

![](http://img.skitch.com/20100208-psmj7mqsx38j1i2nj75n6hbcg7.jpg)

Much better... let's continue.

## Phase Two

We're now going to start installing everything we need to get this
running.

### Ruby 1.8.7.x

First up, Ruby.

Snow Leopard includes Ruby and Rails already installed, but we're going
to back these up for a rainy day. Just issue these commands:
```bash
$ sudo su -
Password:
:~ root# mv /usr/bin/ruby /usr/bin/ruby.orig
:~ root# mv /usr/bin/gem /usr/bin/gem.orig
:~ root# mv /usr/bin/rails /usr/bin/rails.orig
:~ root# logout
```ruby
![](http://img.skitch.com/20100208-b7cxbt8andg3t7ntn17r1wahfg.jpg)

Now we'll go ahead and install a fresh copy of Ruby and RubyGems via
MacPorts.
```bash
sudo port install ruby rb-rubygems
```ruby
You should now see something like this for a bit...

![](http://img.skitch.com/20100208-n9xxiaqbe6bw72qr88dgurxqdp.jpg)

Let's watch a video about bumble bees.

When it finishes installing, you should check that Ruby is available to
you and installed in `/opt/local/bin`.

![](http://img.skitch.com/20100208-tfc3ifeaau15295r9sfmfhbnm1.jpg)

We'll also take a second to create a symlink for this as some tools seem
to rely on `/usr/bin/ruby` being there.
```bash
sudo ln -s /opt/local/bin/ruby /usr/bin/ruby
```bash
Great, let's move on.

### Passenger (mod_rails)

Now that we have Ruby installed, we're going to take a quick detour to
setup Passenger with the Apache server already available on your
machine. I've been a big fan of using Passenger for your development for
over a year now.
```bash
sudo gem install passenger
```ruby
Once the gem is finished installing, you'll need to install the apache2
module with the following command:

It'll ask you to continue by pressing Enter. At this point, it'll check
that you have all the necessary dependencies and then compile everything
needed for Apache2.

![](http://img.skitch.com/20100208-x4rcmr6m5q44etk7rad2kqpmir.jpg)

Now I'll force you to watch a highlights reel of Fernando Torres... *the
best striker in the world!*

The passenger install will then show you this output, which you'll want
to stop and read for a moment and highlight the following:

![](http://img.skitch.com/20100208-ms13ub2srx2axk6ti43ifiyut4.jpg)

Then using vi or emacs, you'll want to create a new file with the
following content:
```bash
vi /etc/apache2/other/passenger.conf
```text
Then paste in the following (what you highlighted and copied above.)
```apache
LoadModule passenger_module /opt/local/lib/ruby/gems/1.8/gems/passenger-2.2.9/ext/apache2/mod_passenger.so
PassengerRoot /opt/local/lib/ruby/gems/1.8/gems/passenger-2.2.9
PassengerRuby /opt/local/bin/ruby
```bash
You'll also want to include the following below what you just pasted.
```apache
# Set the default environment to development
RailsEnv development

# Which directory do you want Apache to be able to look into for projects?
<Directory "/Users/ryangensel/development">
    Order allow,deny
    Allow from all
</Directory>
```ruby
You'll want to quickly start up your web sharing, which will start
Apache2 up via your System Preferences.

![](http://img.skitch.com/20100208-ekr2g6f5seb6iif35fteyjfi74.jpg)

![](http://img.skitch.com/20100208-rm96gmde4d8ffwjbdyqusiqr8f.jpg)

Simple enough... moving forward.

### Passenger Pref Pane

To make things as simple as possible, I'd encourage you to install the
[Passenger Preference
Pane](http://www.fngtps.com/2009/09/new-os-more-pane-passenger-preference-pane-v1-3)
(view this post for a download).

![](http://img.skitch.com/20100208-ra8p88abxtnxbq3m9711gbpryb.jpg)

### Development directory

I have a directory named `development/` in my home directory, which is
where I end up storing all of my projects. This should match whatever
you put above in the apache configuration
(`<Directory "/Users/ryangensel/development">`).
```bash
mkdir development; cd development;
```ruby
### Installing Ruby on Rails via RubyGems

Now we'll use RubyGems to install the latest version of Ruby on Rails
(and all of it's dependencies).
```bash
sudo gem install rails
```ruby
![](http://img.skitch.com/20100208-eyhg4t9sscbeiccs5rxkb5p35.jpg)

While this is installing, you can watch a video from my old band that
ended around the time that business started picking up for [Planet
Argon](http://planetargon.com).

Great, let's test out the install of Rails...

### Test Rails and Passenger

In your development directory, let's quickly a new Rails app...
```bash
rails testapp
```ruby
This will generate a new Rails application in a `testapp/` directory.

Now open up the **Passenger Preferences Pane** and add this directory as
a new application.

![](http://img.skitch.com/20100208-83rjan794eqcmy62e1u4aujtiy.jpg)

![](http://img.skitch.com/20100208-tms89ssutthhq8rkpjm392qfpb.jpg)

Press Apply...

You should now fire up your browser of choice and head to
`http://testapp.local`. If all has worked, you'll see a, "Welcome
aboard" screen from the Ruby on Rails application.

![](http://img.skitch.com/20100208-c9phjdfq8ybcu29uc5k9qiuha9.jpg)

Assuming that this worked for you, let's take a quick break to make some
tea...

## Phase Three

In this last phase, we're going to install a few database servers and
corresponding rubygems so that you can get to work.

### PostgreSQL

At [Planet Argon](http://planetargon.com), we build our web applications
on top of [PostgreSQL](http://postgresql.org). I've been a long-time
advocate of it and hope you consider using it yourself.

At this point in time, the current stable version of PostgreSQL via
MacPorts is 8.4.x. Let's install that now...
```bash
sudo port install postgresql84 postgresql84-server
```text
Once this finishes compiling, you'll need to run the following commands
to setup a new PostgreSQL database.
```bash
sudo mkdir -p /opt/local/var/db/postgresql84/defaultdb
sudo chown postgres:postgres /opt/local/var/db/postgresql84/defaultdb
sudo su postgres -c '/opt/local/lib/postgresql84/bin/initdb -D /opt/local/var/db/postgresql84/defaultdb'
```ruby
Assuming that you want PostgreSQL to always be running, you can run:
```bash
sudo launchctl load -w /Library/LaunchDaemons/org.macports.postgresql84-server.plist
```ruby
...and to start it right now, run:
```bash
sudo launchctl start org.macports.postgresql84-server
```ruby
Before you can start using it, we'll need to make sure that the
PostgreSQL executables are available in your shell path. Since you're
now using [oh-my-zsh](http://github.com/robbyrussell/oh-my-zsh), you'll
want to edit `~/.zshrc` with your favorite editor.
```bash
vi ~/.zshrc
```text
Just append this to `export PATH=` line in the file.
```bash
:/opt/local/lib/postgresql84/bin
```ruby
Your PATH might look something like the following now:
```bash
# Customize to your needs... export PATH=/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/opt/local/lib/postgresql84/bin
```ruby
#### Setup database user

To setup a new database (with superuser credentials), just run:
```bash
createuser --superuser ryangensel -U postgres
```ruby
We'll now test creating a database:
```bash
createdb test_db
```text
Let's test that we can access it...
```bash
➜  ~  psql test_db
psql (8.4.2)
Type "help" for help.

test_db=# \q
```text
Great, let's drop it now.
```bash
➜  ~  dropdb test_db
➜  ~  psql test_db
psql: FATAL:  database "test_db" does not exist
➜  ~
```ruby
Okay, we'll now install the library that will allow Ruby to talk to
PostgreSQL.

Just run:
```bash
sudo gem install pg
```ruby
![](http://img.skitch.com/20100208-b4cf1pm1utkf2ihd9up432etwm.jpg)

Voila... let's move on to the inferior database...

### MySQL

We're going to run through the installation of MySQL really quickly
because you might need it.
```bash
sudo port install mysql5 mysql5-server
```text
This took ages on my machine... so let's watch a video.

We'll now setup the database and make sure it starts on system boot.
```bash
sudo -u _mysql mysql_install_db5
sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist
sudo launchctl start org.macports.mysql5
```text
Let's test that we can create a database now (and that it's running.)
```bash
➜  ~  mysql5 -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.1.43 Source distribution

Type 'help;' or '\h' for help. Type '
```text
Great, now let's install the Ruby library for MySQL.
```bash
sudo gem install mysql -- --with-mysql-dir=/opt/local

Perfect, now we’ve got all the necessary tools to get you working on Ruby on Rails projects with either PostgreSQL or MySQL.

Summary

Thanks for following along with this guide. I hope it helped some of you setup your Snow Leopard environment. We still believe that the ideal hosting environment for your Ruby on Rails applications is a dedicated Linux server. In fact, we’re just about to release our new Boxcar Conductor tool to help with Rails deployments… stay tuned!

In the meantime, feel free to follow me on Twitter or Planet Argon on Twitter.

(oh my) Zsh themes Gone Wild! 18+

December 28, 2009

Earlier this evening, I accepted a pull-request for theme number 18, which is now included in Oh My Zsh. To celebrate, I’ve updated the themes wiki page with fresh screenshots.

Here is a sampling of some of the themes that you can use out of the box with Oh My Zsh.

Oh My Zsh is much more than a collection of themes for your zsh config. It’s a way of life[^1^](#fn1){#fnref1 .footnote-ref role=”doc-noteref”}.

Also, be sure to follow ohmyzsh on twitter now!


  1. ::: {#fn1} well.. at least while you’re in the terminal. ;-)↩︎{.footnote-back role=”doc-backlink”} :::

Sending email: Controllers versus Models

November 16, 2009

While reviewing some code recently, I came across controller code that resembled the following.


if {lang=”ruby”}customer.save CustomerMailer.deliver_welcome_message(customer){lang=”ruby”}
flash[:message] = “Your account has been successfully created. We’ve sent you a welcome letter with…”{lang=”ruby”}
redirect_to dashboard_path{lang=”ruby”}
else{lang=”ruby”}
{lang=”ruby”}
end{lang=”ruby”}\

Fairly typical Rails code. Nothing alarming here, but I wanted to evaluate the call to the mailer in this scenario. When it comes to sending emails from your application, you can choose to do it from the controller as in the example above or in your models. Our team prefers to do this from our model via a callback as we are considering this to be part of our business logic.

Each time a customer is created, we want to send them an email. This can be moved into the model and resembled something like the following..


after_create :send_welcome_message #, other callbacks..

def send_welcome_message
CustomerMailer.deliver_welcome_message(self)
end\

There are a few benefits to doing it this way.

  1. We can test that this is being triggered within our model specs instead of our controller specs. (we prefer to spend more of our time working within models than controllers)
  2. We remove the dependency that all requests must be processed through our controllers.
    • Example: We may one day create rake tasks that data and want these emails to still be sent out. (We’ve had to do this a few times)

I definitely don’t think doing this via controllers is a bad idea, I just lean towards keeping controllers as dumbed down as possible. This allows us to have less controller code that is focused on passing data to/from models and letting our models do the heavy lifting.

UPDATE: DHH was kind enough to post a more detailed response on his blog.

Using BETWEEN for SQL comparisons

November 14, 2009

Recently, Carlos, suggested that I should start sharing some basic SQL tips that help with performance and/or general usage. I recently came across some code that I didn’t like to read and/or write. For example, let’s take the following…

```
SELECT * FROM brochures WHERE published_at <= now() AND archived_at >= now()
```

Essentially, this is pulling back some data WHERE the the brochures are considered published. (We have a project that allows people to manage their brochure launch dates ahead of time.) In fact, in this project, we have no less than 6-8 dates in the database that we’re comparing data on and it’s easy to get lost in the logic when trying to understand it.

Now, there isn’t anything inheriently wrong with how this condition is constuctued. As a matter of personal taste, I find it annoying to mentally parse. Also, I find having to write now() more than once in a WHERE clause to feel like I’m repeating myself.

Read it outloud…

“WHERE the brochures published at date is less than and/or equal to right now AND the archived date is greater than and/or equal to now.”

Who talks like that?

Luckily, there is a better and in my opinion, a more readable way to express this is with the BETWEEN construct in SQL. (postgresql docs, mysql docs)

```
SELECT * FROM brochures WHERE now() BETWEEN published_at AND archived_at
```

Let’s read this outloud…

“WHERE the current date is between the published at and archived at dates.”

This sounds more natural to me.

Additionally, you can also do the inverse with NOT.

```
SELECT ... WHERE now() NOT BETWEEN brochures.published_at AND brochures.archive_at
```

Remember kids, “code is for humans first and computers second.” — Martin Fowler

Planet Argon Podcast, Episode 3: How We Manage Bugs

November 11, 2009

Earlier this week, we published Episode 3 of the Planet Argon Podcast. In this latest episode we responded to one of the ideas someone in the audience asked on this brainstormr, which was, “How do you manage bugs?”

We had a round table discussion about how we classify and prioritize bugs with our clients, ticketing systems, and other tools that we use to streamline this process.

You can listen to this on iTunes or online.

Tracking Google Analytics events in development environment with GoogleAnalyticsProxy

November 01, 2009

As mentioned in a recent article[^1^](#fn1){#fnref1 .footnote-ref role=”doc-noteref”}, I’ve been diving deep into Google Analytics lately while working on a few client projects. We’re aiming to use much more of the features of Google Analytics and have been hitting some roadblocks with the development versus production application environments. Once you begin to dive into event tracking and AJAX-driven goal conversions, relying on just the sample code that Google Analytics provides you is going to result in you looking at a handful of JavaScript errors.

::: thumbnail pageTracker is not
defined :::

another example from the firebug javascript console…

::: thumbnail firebug pageTracker is not
defined :::

We see JavaScript errors like this because we don’t load the google analytics code in our development environments. As you can see, we are only loading this in our production environment.


<% if RAILS_ENV 'production' -%> <!--// Google Analytics //--> <script type="text/javascript"> var gaJsHost = (("https:" document.location.protocol) ? “https://ssl.” : “http://www.”);
document.write(unescape(“%3Cscript src=’” + gaJsHost + “google-analytics.com/ga.js’ type=’text/javascript’%3E%3C/script%3E”));

<% end -%>\

To track an event with Google Analytics, you’d need to trigger something like:


pageTracker._trackEvent(‘Button’, ‘Click’, ‘Get in touch’);{lang=”ruby”}\

As you can see from our code earlier, in development, the pageTracker variable isn’t defined and that’s why we’re getting those JS errors. We also don’t want to add conditionals everywhere in our application to check if we’re in development or production environment.. as that’d just make our views uglier than they need to be. So, I decided that I’d create a proxy class in JavaScript that would allow us to trigger _trackEvent() and _trackPageview() and handle it appropriately.

This class works with the following logic:

  • if google analytics is loaded, pass the parameters to the real pageTracker
  • if google analytics is NOT loaded, output the information to console.log() for debugging purposes

For example, on a gallery on our web site… we track when people navigate next and/or previous through the photos. In our development environment, I can watch the JavaScript console output the following:

::: thumbnail Firebug -
GAP :::

And in our production environment, we can see that this was sent to Google Analytics.

::: thumbnail Firebug -
trackEvent() :::

We’re able to do this by initializing the GoogleAnalyticsProxy class and calling these functions through it. For example:


_gap = new GoogleAnalyticsProxy();{lang=”ruby”}
_gap._trackEvent(‘Video’, ‘Play’, ‘Homepage video’);{lang=”ruby”}
_gap._trackEvent(‘Video’, ‘Pause’, ‘Homepage video’);{lang=”ruby”}
_gap._trackEvent(‘Button’, ‘Click’, ‘Call to action X’);{lang=”ruby”}\

You’ll see that we’re just calling _gap versus pageTracker. We then replace all the instances of pageTracker (except where it is defined in the google analytics code block they provide you). You’ll find this located near the bottom of our application.html.erb file.


<% if RAILS_ENV 'production' -%> <!--// Google Analytics //--> <script type="text/javascript"> var gaJsHost = (("https:" document.location.protocol) ? “https://ssl.” : “http://www.”);
document.write(unescape(“%3Cscript src=’” + gaJsHost + “google-analytics.com/ga.js’ type=’text/javascript’%3E%3C/script%3E”));

<% end -%>

We now have _gap available throughout our project and can call _trackEvent() and _trackPageview() with it. Note: You can use any JS variable name that you want, _gap is just what I went with.

Get GoogleAnalyticsProxy

I’ve gone ahead and tossed this small JavaScript class (known as GoogleAnalyticsProxy) on Github for your enjoyment. I have some more articles in the works that will show you some tips for how to make the most of Google Analytics. If you have any questions and/or ideas for related article topics, don’t hesitate to let me know.


  1. ::: {#fn1} Tracking AJAX-driven events in Ruby on Rails for Google Analytics conversion goals↩︎{.footnote-back role=”doc-backlink”} :::

Planet Argon Podcast, Episode 2: The Letter Scotch

October 30, 2009

Earlier this week our new podcast was approved and is now available in the Apple iTunes Store. We’re also soliciting topic ideas for future episodes on brainstormr.

We posted Episode 2, The Letter Scotch, yesterday for your enjoyment. In this episode, we covered a handful of web browser tools that we use (and detest) to debug HTML, CSS, and JavaScript. This included Web Inspector, Firebug, DebugBar, and a handful of other tools. We all have slightly different preferences, depending on the tasks that we’re working on and the team had an open dialogue about the pros/cons of each of these tools.

You can learn more about and listen to our podcast at http://planetargon.com/podcast.

Thanks in advance for listening!

Tracking AJAX-driven events in Ruby on Rails for Google Analytics conversion goals

October 21, 2009

Tracking your KPI’s is extremely important in your online venture. At a minimum, you should be using something like Google Analytics to track conversions in your application. Setting up goals is actually quite simple, especially if you’re just tracking that specific pages are loaded. However, if some of your conversion points occur through AJAX, you might not be capturing those activities in Google Analytics.

Lucky for you, it’s actually quite simple to update this. I thought I’d show you a fairly simple example to help you along.

On our web site, we have a mini contact form at the bottom of many of our pages. When submitted, if JavaScript is enabled, it’ll perform an Ajax request to submit the form. If you fill out the main Get in Touch form that gets processed and we redirect people to a thank you page. The URL for that is unique and we’re able to track those in Google Analytics quite easily.

However, with the Ajax-form, the URL in the browser isn’t going to change so Google Analytics isn’t going to track that conversion. So, we needed to track that properly.

To do this, we just need to call a JavaScript function that the Google Analytics code provides you.


pageTracker._trackPageview(“/contact_requests/thanks”);{lang=”ruby”}\

Let’s look at some simple code from our controller action. If the request is from JavaScript, we currently replace the form area with the content in a partial. (note: if you’re curious about the _x, read Designers, Developers and the x_ factor)


respond_to do |format|{lang=”ruby”}
format.html { redirect_to :action => :thanks }{lang=”ruby”}
format.js do{lang=”ruby”}
render :update do |page|{lang=”ruby”}
page.replace :x_mini_contact_form_module, :partial => ‘mini_contact_form_thanks’{lang=”ruby”}
end{lang=”ruby”}
end{lang=”ruby”}
end{lang=”ruby”}\

As you can see, the redirect will within the format.html block will lead people to our conversion point. However, the format.js block will keep the user on the current page and it’ll not trigger Google Analytics to track the conversion. To make this happen, we’ll just sprinkle in the following line of code.


page.call ‘pageTracker._trackPageview(“/contact_requests/thanks”);’{lang=”ruby”}\

However, if you need to do something like this in several locations in your application, you might want to just extend the JavaScriptGenerator page. GeneratorMethods. (you could toss this in lib/, create a plugin, etc…)


module ActionView{lang=”ruby”}
module Helpers{lang=”ruby”}
module PrototypeHelper{lang=”ruby”}
class JavaScriptGenerator #:nodoc:{lang=”ruby”}
module GeneratorMethods{lang=”ruby”}
# Calls the Google Analytics pageTracker._trackPageview function with {lang=”ruby”}[path{lang=”ruby”}]{.underline}.{lang=”ruby”}
#{lang=”ruby”}
# Examples:{lang=”ruby”}
#{lang=”ruby”}
#{lang=”ruby”}
# # Triggers: pageTracker._trackPageview(‘/contact_requests/thanks’);{lang=”ruby”}
# page.track_page_view ‘/contact_requests/thanks’{lang=”ruby”}
#{lang=”ruby”}
def track_page_view(path){lang=”ruby”}
record “pageTracker._trackPageview(‘#{path}’);”{lang=”ruby”}
end{lang=”ruby”}
end{lang=”ruby”}
end{lang=”ruby”}
end{lang=”ruby”}
end{lang=”ruby”}
end{lang=”ruby”}\

This will allow us to do the following:


page.track_page_view “/contact_requests/thanks”

# or using a route/path
page.track_page_view thanks_contact_requests_path\

So, our updated code now looks like:


render :update do |page|{lang=”ruby”}
page.replace :x_mini_contact_form_module, :partial => ‘mini_contact_form_thanks’{lang=”ruby”}
page.track_page_view thanks_contact_requests_path{lang=”ruby”}
end{lang=”ruby”}\

With this in place, we can sprinkle similar code for our various conversion points that are Ajax-driven and Google Analytics will pick it up.

Happy tracking!