Phusion Passenger 2.0 debuts at Railsconf 0

Posted by carl

The Phusion Passenger guys really dropped a bomb at their Railsconf presentation today, which unfortunately was poorly attended. Their successful copy-on-write improvements to Ruby (released as Ruby Enterprise Edition) and their improved queueing mechanisms in the Passenger Apache module make it currently the Rails deployment option with the fastest execution times and the lowest memory footprint, even when compared with nginx and thin servers in front of mongrel clusters.

On top of this, they announced that the mod_rails moniker has been abandoned, since it now supports Rack (which allows you to host things like Camping and Merb apps) and WSGI, which even lets it run things like Django (!)

I personally am really excited that Dreamhost has installed Passenger, which makes it so much easier for me to host my personal Rails apps.

Another great keynote by David Hansson 0

Posted by carl

I really enjoyed David Hansson’s keynote at RailsConf this year. He started out by discussing the surplus, or competitive advantage that Rails created, and how this surplus will eventually disappear, probably for one of three reasons:
  • Other frameworks/languages will achieve what Rails has (unlikely)
  • Another breakthrough technology will arrive
  • Rails will become mainstream (good and bad)
My favorite part was near the end, where he admonished Rails developers to become better programmers by being more well-rounded. Among his suggestions for doing this were:
  • Read more paper (reduce RSS feeds)
  • Take up a hobby (examples: wood carving, banjo playing, pilot’s license)
  • Get more sleep
  • Reduce work time

On a side note, I have had a lot of people lament, along with me, that Confreaks wasn’t contracted to record RailsConf. Our services become especially useful at multi-track a conference like this, where you seem to always want to be watching more than one presentation at a time. While I wish we were recording it, it is also nice to be able to sit back and relax and just watch a conference for a change.

Interview with Fabio Akita 0

Posted by carl

I recently spent a few enjoyable hours chatting with Fabio Akita about my involvement in the Ruby community and my thoughts about software development. Fabio is one of the developers I manage as part of my job at Surgeworks. He is a very skilled programmer and a great guy to work with.

Making migrations easier 0

Posted by carl

One of my most common problems when developing migrations for a rails project happens when I make a mistake in my migration code that causes the migration to fail to complete successfully. When this happens, it is often the case that some of the commands in your migration executed successfully. This means that when you fix your bug and try to run the migration again, it will fail because it will attempt to run the previously successful commands but will complain that the changes they refer to are already there. There are some workarounds for this, such as using the :force => true option, but even then there are some situations that are hard to recover from. I often ended up having to manually drop my database and re-create it and then run the migration again—a real pain. So I finally decided to make a rake task that would make this a lot easier.

namespace :db do
  task :nuke => :environment do
    abcs = ActiveRecord::Base.configurations
    ["development", "test"].each do |db|
      case abcs[db]["adapter"]
        when "oci"
          ActiveRecord::Base.establish_connection(db.to_sym)
          conn = ActiveRecord::Base.connection
          conn.begin_db_transaction
          conn.tables.each do |table|
            indexes = conn.indexes(table)
            indexes.each do |ind|
              puts "Dropping index #{ind.name}"
              conn.execute("DROP INDEX #{ind.name}")
            end
            puts "Dropping table #{table}"
            conn.execute("DROP TABLE #{table}")
          end
          sql = "SELECT LOWER(sequence_name) FROM user_sequences"
          sequences = conn.select_all(sql).inject([]) do |seqs, s|
            seqs << s.to_a.first.last
          end
          sequences.each do |seq|
            puts "Dropping sequence #{seq}"
            conn.execute("DROP SEQUENCE #{seq}")
          end
          conn.commit_db_transaction
        when "mysql"
          ActiveRecord::Base.establish_connection(db.to_sym)
          conn = ActiveRecord::Base.connection
          conn.execute("DROP DATABASE #{abcs[db]["database"]}")
          conn.execute("CREATE DATABASE #{abcs[db]["database"]}")
          ActiveRecord::Base.establish_connection(db.to_sym)
        when "sqlite", "sqlite3"
          dbfile = abcs[db]["database"] || abcs[db]["dbfile"]
          File.delete(dbfile) if File.exist?(dbfile)
          ActiveRecord::Base.establish_connection(db.to_sym)
        else
          raise "Task not supported by '#{abcs[db]["adapter"]}'"
      end
      ENV['RAILS_ENV'] = db
      Rake::Task["db:migrate"].dup.invoke
      Rake::Task["db:fixtures:load"].dup.invoke
    end
  end
end

Save the text above into lib/tasks/db_nuke.rake. This task (run it using rake db:nuke) will completely drop your dev and test databases, run all migrations on them, and run rake db:fixtures:load on them. It works on mysql and sqlite. Adapting it for postgres or some other database is left as an exercise for the reader.

Update: I added a dependency on the environment, rather than trying to include the environment files manually. This is the "right" way to do it.

Update: I have added Oracle support.