Tuesday, February 16, 2010

Multi-level Single Table Inheritance (STI) in Rails

This took me more than one attempt to get right, so I thought I'd blat it out in a blog post in case anyone else has been struggling with it. In the end, the implementation matches your intuition, but getting the sub-classing syntax right took a few tries (undoubtedly due to my relative newness to Rails/Ruby).

Why would you want multi-level STI? When you're using multiple inheritance (class_c inherits from class_b and class_b inherits from class_a) and you want that relationship maintained through ActiveRecord; that's when.

Take the following three classes for example:

/app/model/a/class_a.rb
class A
def method_a
"a"
end
end

/app/model/a/class_b.rb (yes, I mean dir 'a'. class_b.rb is a peer of class_a.rb)
class A::B < A
def method_b
"b"
end
end

class A::B::C < A::B
def method_c
"c"
end
end


Notice the explicit class hierarchy notation. Without this, I can't get the multi-level relationship maintained through STI.

From here, you can merrily create the class through ActiveRecord, assuming you have an existing table for the base class (which includes the 'type' column (where AR stashes the class hierarchy/name information for subsequent instanciations), and use all the methods.


A::B::C.create!
...
c = A.first
c.method_a => 'a'
c.method_b => 'b'
c.method_c => 'c'

Friday, February 5, 2010

Google Chrome for Mac

I spent the past few days with Google Chrome for Mac as my default browser on my primary machine. I tweeted some notes about the experience if you're interested in the details.

I've reverted my default back to Firefox (3.6) however because of page incompatibility (rendering, JS execution, and lacking plugin support) issues I just don't have time to workaround with a new browser.

What I did like about the experience however were the DNS pre-caching optimizations that Google incorporated, and how child-tabs were handled; nice work!

Building a browser is hard. Good luck Google.