Monday, August 13, 2007

Driving on the Wrong Side of Ruby Street

Fellow 3TG Jake gave Ruby such a ringing endorsement (paraphrased) "everytime I start something in a non-Rails environment, I think why bother?"during the last geek night that I thought I'd take his advice and use it for all my home grown projects. Well the more I use Rails, the more I agree. The learning curve is a little steep, but there are productivity and ease of coding gains to be had.

This weekend I had a need to do a LEFT JOIN. It was pretty much identical to the example laid out on the Ruby website.

class User < ActiveRecord::Base
# I reference an account.
belongs_to :account
end

class Account < ActiveRecord::Base
# One user references me.
has_one :user
end

CREATE TABLE users (
id int(11) NOT NULL auto_increment,
account_id int(11) default NULL,
name varchar default NULL,
PRIMARY KEY (id)
)

CREATE TABLE accounts (
id int(11) NOT NULL auto_increment,
name varchar default NULL,
PRIMARY KEY (id)
)

However, in my example instead of "users" I had a composite table name. Something like UserAccounts. Rails wants you to name the table user_accounts. But I'm not 100% up on the Ruby Way principals. I had named the table "UserAccounts" and went on my way not giving it two thoughts.

My first swing at this with a little help from Google was to write my own SQL along the lines of:

sql = "select u.* from users u left JOIN useraccounts ac ON u.account_id=ac.id where ac.id is null"
@user_pages, @user = paginate_by_sql User, sql, 20

However, Jake's first comment upon hearing this was, why didn't you do something like:

Account.find(:all, :include => :user)

I thought, okay, in the interest of learning better learning Rails I thought I try it Jake's way. But I ran into problems. The only error message I kept receiving was "ActiveRecord::StatementInvalid". It turns out that normally the database adapter would've notified me of the issue. However, I'm running SQLite3 as my database. It turns out this means the database adapter is not quite as verbose as the other ones.

After a bit of frustrating and some googling I came across this. Basically it says there's a bug in sqlite_adapter.rb. After modifying the file with the recommended changes, Rails told me that I needed to make a simple change to the database table name.

Two hours later and after having to modify the ruby sqlite3 adapter I believe I'm heading the right way Ruby Street. I am little frustrated, but hopefully better off.