Friday, December 14, 2007

Beware reserved words in legacy databases

This took me a damn long time to figure out.  My rails app is using a legacy database for part of its data source.  It was quite complicated: I was using multiple databases in Rails, namespaced models, non-standard table names (with set_table_name), and non standard primary keys (with set_primary_key).  So when things like ActiveRecord associations didn't work, I figured that it was because I was trying to force this mess into the Rails conventions and just having no luck.

Turns out, it was something simple.

I continued to strip away more and more of the messy configurations -- got rid of associations, moved the tables into the same database temporarily, renamed tables and primary keys, etc.  But still no luck.  Just trying to access a simple attribute from the model in the console would result in this incredibly helpful error message:

  undefined method `generated_methods' for 8:Fixnum

What?  And to make it worse, a Google search for this error turned up nothing.  Nothing as in "no results found," not the typical Google result junk.  Well, I won't tell you how long it took me to figure out this problem, but it came down to this:  One of my legacy tables (the main one) had a column name in it called class.  It's supposed to represent a student's class standing in school.  Well, of course, "class" is a reserved word in Ruby, so therefore all hell breaks loose in situations like this.  Dammit.

Is there no way for Rails to check for this?  Why wasn't there a helpful "Cannot use reserved word here" error instead of the useless one above?  Rails was able to get the column listing from the table just fine.  The problem only happened when it tried to do its "Rails magic" and auto-generate all of those handy accessor methods.  So why not do a quick check on the column listing for reserved words?

Either way, it's fixed now with a simple mapped column in the DB.  Time for the weekend.