Hi, I'm Sam.

I like to create software, make music, and write about technology.

Find out more about me.

#rails Posts

Compass and Rails 3.1

Posted in compass, css, development, and rails

Here's how I finally got Compass working with Rails 3.1rc4 (with includes, sprites, etc).

Gemfile excerpt:

gem 'sass-rails', :git => 'https://github.com/rails/sass-rails.git', :ref => '031236b31eaf20658226a9ae051749cc6647c33f'
gem 'compass', :git => 'https://github.com/chriseppstein/compass.git', :ref => '2c1fcfcad708875d10db65740aabf417abc636a6'
gem 'sprockets', '2.0.0.beta.10'

config/compass.rb excerpt:

http_images_path = '/assets/'

That's it. You don't have to do any of the crazy initializer hacks or anything like that. (If you were doing that, you can remove it all). The rest of my Gemfile and compass.rb are just standard stuff. Here's my full compass.rb if that helps though.

The only other thing you'll need to do is be sure all of your stylesheets are in app/assets/stylesheets/ and end in .css.scss or .css.sass. Eventually you won't have to include the .css part if you don't want to, but for now, it's required (due to Sprockets).

Big thanks to Jon McCartie and
Chris Eppstein
for all of their help!

Update: Rails 3.1.0.rc5

Rails 3.1.0.rc5 just came out. Here's the updates for rc5.

Gemfile excerpt:

gem 'sass-rails', :git => 'https://github.com/rails/sass-rails.git', :ref => '231b14da040c3ad320076cbaaa70190d14b95d37'
gem 'compass', :git => 'https://github.com/chriseppstein/compass.git', :ref => '33263caffe5548a64253976c0a034afe1ed567f4'

That's it! Your compass.rb remains the same as before with http_images_path. You don't need to add .css to partials' file names any more now!

My Take on using Ruby on Rails

Posted in development, javascript, php, rails, and web

So I recently decided to give Ruby on Rails another chance. For many of the same reasons I gave jQuery a chance. I'll use this decision as an example, so bear with me for a second.

I was a huge fan of MooTools (and still am), but I decided to give jQuery a chance. I liked MooTools better. I thought it was superior to jQuery in its organization and many other things. You have to admit that MooTools's animations look way better.

All of that said, two things made me switch: the amount of code I didn't have to write and the huge community around it.

With jQuery you write a lot less code than you do with MooTools. I sometimes feel that its a lot less elegant, but less code equals quicker development time.

My biggest frustration with MooTools was that they changed major stuff in every release (at least when I was using it about a year ago). This means that if you needed a lightbox, you could find a few, but none of them would work with the current version. If you searched for jQuery ones, you could find tons of them.

On to Rails

I took the same approach when I was giving Ruby on Rails another chance. I knew the community was huge. It seems Rails is growing in popularity every day. All of the PHP programmers I knew were either dabbling in WordPress or writing really ugly, non-MVC code. It just seems that it's hard to find a PHP programmer doing cool stuff these days. I know a few don't get me wrong, the number just seems less and less.

Any one writing stuff in Rails is doing it in the MVC (model, view, controller) design pattern. I'm a huge MVC fan, so that was attractive to me.

First Impressions

I watched Creating a weblog in 15 minutes from the Ruby on Rails website. It blew me away. It was amazing how much code you didn't have to write, which is the entire purpose of a framework. A framework is designed to solve common problems so everyone doesn't have to solve them again and again. Rails seemed to solve more of these problems than any other framework I've used, and it did it very well.

I downloaded Rails and gave it a shot. I just followed along with that video to create a simple weblog in an hour or so. I was really impressed with myself on how quickly I could code it.

But, Rails isn't as good as PHP is it?

Well that depends on how you define "good". To me a good web development environment is one that lets me develop the quickest. Before Ruby on Rails it was KohanaPHP (which I totally recommend if you're using PHP). If Rails lets me developer faster and write less code (which generally equals less bugs), then to me that makes it a win. I believe it does. There is way less code in my Rails version of my blog than my Kohana one.

It has been proven many times that Ruby is slower than PHP. That doesn't bother me at all. If I'm writing a large web app, I'm going to be caching as much as possible anyway, so what's the point. If I can roll out features quicker at a tiny performance hit for when the cache misses, that is a win in my book.

Running Rails Local Development with Nginx, Postgres, and Passenger with Homebrew

Posted in development, heroku, homebrew, local-development, nginx, passenger, postgres, and rails

Lately I have been playing with Homebrew, an awesome package manager for Mac OS X. I really like not having to worry about dependencies and such when installing. The "rarely sudo" mentality is also pretty great.

When I noticed the Nginx (a sweet open source web server that is way better than Apache) had a --with-passenger option (which is also way awesome), I figured I'd give it a shot. I was using the built-in Apache with Passenger Preference Pane, which was pretty cool, but I really like Nginx, so I switched. I also really wanted to start using PostgreSQL instead of SQLite since all of my stuff is hosted on Heroku and that's what they're running. (I do plan on writing a Preference Pane for doing for this setup eventually.)

Here are the steps to get all of this going. I tried to keep it as simple and clear as possible with lots of examples. It looks like a lot, but it's really quite simple.

This probably goes without saying, but you'll need Xcode installed to do all of this.

Installation

  1. Install Homebrew and follow the steps in the wiki about not sudoing when installing RubyGems.

    If you don't want to do it that way (I highly recommend doing it the above way), you can just run this command to install homebrew.

    $ sudo chown -R $USER /usr/local
    $ curl -Lsf http://github.com/mxcl/homebrew/tarball/master | tar xvz -C/usr/local --strip 1
    

    You'll need to sudo install gems if you do it this way.

  2. Install the Passenger gem

    $ gem install passenger
    

    I also had to install the fastthread gem to get Passenger to play nice later. You might not have to do this. If you need to, all you have to do is gem install fastthread.

  3. Install Nginx with the Passenger module

    $ brew install nginx --with-passenger
    

    You can start Nginx with sudo nginx and stop it with sudo nginx -s stop.

  4. Install PostgreSQL

    $ brew install postgresql
    

    After the installation completes, there will be instructions on how to initialize the database, start the server, start the server at login, and install the pg gem. Do all of this.

Server Configuration

  1. Modify your Nginx configuration for Passenger. It will be located at /usr/local/Cellar/nginx/0.7.62/conf/nginx.conf (obviously you will need to replace the version number with whatever version you installed). Here is what mine looks like.

    user samsoffes staff;
    worker_processes 1;
    
    error_log logs/error.log;
    
    events {
      worker_connections  1024;
    }
    
    http {
      include mime.types;
      default_type application/octet-stream;
    
      # Passenger
      passenger_root /usr/local/Cellar/Gems/1.8/gems/passenger-2.2.7;
      passenger_ruby /usr/local/bin/gem_ruby;
      passenger_default_user samsoffes;
    
      sendfile on;
      keepalive_timeout 65;
    
      # Include virtual host configurations
      include samsoffes.conf;
    }
    

    There are a few things to note:

    1. I run it as my user (staff is my group). You don't have to do this, but I like to have the processes running as me. (If there are more of me, I'm more productive, right?) You'll need to comment this line out or change to your user.
    2. I am pointing the passenger_root directive to the passenger root. This will change with whatever version of Passenger you have installed. You can get the current path by running passenger-config --root (you'll probably need to do this since the version is in the path).
    3. I also have passenger_ruby set to gem_ruby. I had a horrible time getting Passenger to see my custom GEM_PATH (that I setup by following the Homebrew wiki). I created this little shell script to fix the environment variables. It would be great if Passenger had a way to do this. I know you can in the Apache version, but I couldn't figure it out for Nginx. Here is what my gem_ruby looks like:

      #!/bin/bash
      export GEM_PATH=/usr/local/Cellar/Gems/1.8:/System/Library/Frameworks/Ruby.framework/Versions/Current/usr/lib/ruby/gems/1.8/gems
      export GEM_HOME=/usr/local/Cellar/Gems/1.8
      
      /usr/bin/ruby $*
      
  2. I like to keep all of my virtual hosts in separate files in the conf directory and then include them into nginx.conf, but you can do it however you want. Here is what samsoffes.conf looks like:

    server {
      listen 80;
      server_name samsoffes.local;
      root /Users/samsoffes/code/samsoffes/samsoff.es/public;
    
      rails_env development;
      passenger_enabled on;
    
      charset utf-8;
    }
    
  3. You will need to edit your /etc/hosts for any virtual hosts you add. Mine looks like this:

    ##
    # Host Database
    #
    # localhost is used to configure the loopback interface
    # when the system is booting.  Do not change this entry.
    ##
    127.0.0.1   localhost
    255.255.255.255 broadcasthost
    ::1             localhost 
    fe80::1%lo0 localhost
    127.0.0.1 samsoffes.local
    

Database Configuration

  1. If you haven't already, edit your application's database.yml file to use PostgreSQL. Here is an example:

    development:
      adapter: postgresql
      database: samsoffes_development
      encoding: utf8
      username: samsoffes
      password:
      host: localhost
    
    production:
      adapter: postgresql
      database: samsoffes_production
      encoding: utf8
      username: samsoffes
      password:
      host: localhost
    
    test:
      adapter: postgresql
      database: samsoffes_test
      encoding: utf8
      username: samsoffes
      password:
      host: localhost
    

    Notice that the username is samsoffes and not root. Using the root user is considered bad practice by most. (We'll create that user in the next step.)

  2. Enter the PostgreSQL prompt to create your user and databases:

    $ psql  postgres
    # CREATE USER samsoffes SUPERUSER;
    # CREATE DATABASE samsoffes_development OWNER samsoffes;
    # CREATE DATABASE samsoffes_test OWNER samsoffes;
    # \q
    

    Note: you need to make your user a superuser for your tests to run correctly. More on this here.

Let's get started already!

So, to review, you have just installed and configured Nginx, Passenger, and PostgreSQL. Now, all you have to do is type sudo nginx to start Nginx and point your browser to your virtual host (so for me it would be http://samsoffes.local). That's it! You're done!

If you forgot to copy the commands out of the PostgreSQL install, here's how to start and stop PostgreSQL:

# Start
$ pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start

# Stop
$ pg_ctl -D /usr/local/var/postgres stop -s -m fast

Before, I found myself typing sudo apachectl restart a lot to reload my application. Now, you would run sudo nginx -s reload to reload the server configuration and restart the app. (You can of course do the touch tmp/restart.txt method as well.)

That probably seemed a bit tedious, but now all you have to do is create a virtual host in Nginx, add it your your hosts file, and create your database. I really like developing locally like this. Homebrew makes this entire process very easy.

If you have any issues, feel free to send me an email and I'll see what I can do. (I really need to get comments going on here don't I)