Inheritance in Ruby on Rails
I have a Rails project I’m working on that seems to be best suited for class table inheritance. Conceptually it will greatly simplify the database and reduce tons of code. There will be a performance hit due to the extra joins. I think that will be manageable though and the simplification of the entire site architecture will make it well worth it. The problem is that class table inheritance isn’t currently implemented in Ruby on Rails and requires a hack to make it work. I’m weary about implementing this hack mostly for long term maintainability since its such a crucial aspect of the site’s architecture. Ideally, class table inheritance will eventually be built into the Rails core but who knows when that’ll happen.
Then I found the inherits_from plugin which made me a bit more comfortable so I tried it out. It works in a very primitive way so long as I’m not using any conditions in my find commands. For instance if I had a product that stored a name and a car table which is going to inherit everything from the products table:
[source language=":ruby"]
car = Car.find(:first)
car.name
[/source]
car.name works fine and it would be great if that’s the only way I ever needed to use it. The problem is when I try to toss some conditions into the mix that are conditions against the parent model. So if my products table also had color and I wanted to do something like:
[source language=":ruby"]
car = Car.find(
:first,
:conditions => ['products.color = (?)', 'blue'])
car.name
[/source]
It doesn’t work because its not doing a join but rather 2 separate queries. 1 query for the car table to get the product_id and the other on the products table. Using:
[source language=":ruby"]
car = Car.find(
:first,
:conditions => ['color = (?)', 'blue'])
car.name
[/source]
Doesn’t work either. The solution? One option is to extend ‘find’ to make it recognize when its supposed to do a join instead of 2 queries. I’m not looking forward to hacking that mess up cause it opens a big can of worms. For example, how would it handle pagination with conditions as well? I’m not using the plugin. After my getting to that point with the plugin I decided to take another look at the first hack I linked to and see how much effort it really is going to take to get this thing working. I might just end up scrapping class table inheritance altogether and accept the big messy database structure and code redundancy that will ensue.
Pingback: » Class table inheritance in Ruby on Rails » My geek blog - Brian McQuay