CTI in ActiveRecord

To my knowledge rails only supports STI or separate tables for each
subclass. If you make People abstract then each subclass will be in
its own tale.

The hybrid you show is not directly supported. You would need to
model them as associated tables. But, if you think about it that
makes sense. How would you expect a row in the employee table to
connect to a row in the people table? The best way is to add a
people_id to employee. That becomes a :belongs_to and you are all
set. You can always add support in Employee for delegating to the
associated people object so to the user they appear to be subclasses.


In Rails you can use STI very easily. The following example should
clearify things (from Agile Web Development with Rails, you should buy
the book at http://www.pragmaticprogrammer.com/ ):

create_table :people, :force => true do |t|
  t.column :type, :string

  # common attributes
  t.column :name, :string
  t.column :email, :string

  # attributes for type=Customer
  t.column :balance, :decimal, :precision => 10, :scale => 2

  # attributes for type=Employee
  t.column :reports_to, :integer
  t.column :dept, :integer

  # attributes for type=Manager
  # - none -

class Person < ActiveRecord::Base

class Customer < Person

class Employee < Person
  belongs_to :boss, :class_name => "Employee" , :foreign_key
=> :reports_to

class Manager < Employee

Customer.create(:name => 'John Doe' , :email =>
"john@doe.com" , :balance => 78.29)
wilma = Manager.create(:name => 'Wilma Flint' , :email =>
"wilma@here.com" ,:dept => 23)
Customer.create(:name => 'Bert Public' , :email =>
"b@public.net" ,:balance => 12.45)
barney = Employee.new(:name => 'Barney Rub' , :email =>
"barney@here.com" ,:dept => 23)
barney.boss = wilma

manager = Person.find_by_name("Wilma Flint" )
puts manager.class #=> Manager
puts manager.email #=> wilma@here.com
puts manager.dept #=> 23

customer = Person.find_by_name("Bert Public" )
puts customer.class #=> Customer
puts customer.email #=> b@public.net
puts customer.balance #=> 12.45