# CTI in ActiveRecord

**URL:** <https://www.ruby-forum.com/t/cti-in-activerecord/105325>\
**Category:** Rails\
**Created:** [May 28, 2007, 9:06pm UTC](https://www.ruby-forum.com/t/cti-in-activerecord/105325 "2007-05-28T21:06:50Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mr\_brownstone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/59ef9b/32.png) [@mr\_brownstone](https://www.ruby-forum.com/u/mr_brownstone)\
**Post date:** [May 28, 2007, 9:06pm UTC](https://www.ruby-forum.com/t/cti-in-activerecord/105325/1 "2007-05-28T21:06:50Z")

</div>

I search an plugin or gem, but don’t find nothing satisfactory. I  
believe to be stranger a technology that nails the DRY, have that create  
you vary equal tables, instead of using inheritance.

Exists an soluction for this? I want a solution similar to this:

create\_table :people |t| do  
t.column :name  
t.column :address  
end

create\_table :customer |t| do  
t.column :person\_id  
t.column :cpf  
end

create\_table :employee |t| do  
t.column :person\_id  
t.column :wage  
end

class Person \< ActiveRecord::Base  
end

clas Customer \< Person  
end

class Employee \< Person  
end

Cusotmer.name  
Customer.cpf

Employee.name  
Employee.wage

---

<div class="post-metadata">

**Author:** ![mr\_brownstone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/59ef9b/32.png) [@mr\_brownstone](https://www.ruby-forum.com/u/mr_brownstone)\
**Post date:** [May 28, 2007, 9:24pm UTC](https://www.ruby-forum.com/t/cti-in-activerecord/105325/2 "2007-05-28T21:24:07Z")

</div>

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.

Michael

On May 28, 12:06 pm, Marcelo J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![mr\_brownstone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/59ef9b/32.png) [@mr\_brownstone](https://www.ruby-forum.com/u/mr_brownstone)\
**Post date:** [May 28, 2007, 9:30pm UTC](https://www.ruby-forum.com/t/cti-in-activerecord/105325/3 "2007-05-28T21:30:29Z")

</div>

MichaelLatta wrote:

> 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.
> 
> Michael

This is not inheritance, but relationship. What I want inheritance.

Some plugin or gem?

---

<div class="post-metadata">

**Author:** ![mr\_brownstone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/59ef9b/32.png) [@mr\_brownstone](https://www.ruby-forum.com/u/mr_brownstone)\
**Post date:** [May 28, 2007, 9:32pm UTC](https://www.ruby-forum.com/t/cti-in-activerecord/105325/4 "2007-05-28T21:32:40Z")

</div>

CTI = DRY

---

<div class="post-metadata">

**Author:** ![mr\_brownstone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/59ef9b/32.png) [@mr\_brownstone](https://www.ruby-forum.com/u/mr_brownstone)\
**Post date:** [May 29, 2007, 6:39pm UTC](https://www.ruby-forum.com/t/cti-in-activerecord/105325/5 "2007-05-29T18:39:00Z")

</div>

In Rails you can use STI very easily. The following example should  
clearify things (from Agile Web D. with Rails, you should buy  
the book at [http://www.pragmaticprogrammer.com/](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 -

end

class Person \< ActiveRecord::Base  
end

class Customer \< Person  
end

class Employee \< Person  
belongs\_to :boss, :class\_name =\> “Employee” , :foreign\_key  
=\> :reports\_to  
end

class Manager \< Employee  
end

Customer.create(:name =\> ‘John D.’ , :email =\>  
“removed\_email\_address@domain.invalid” , :balance =\> 78.29)  
wilma = Manager.create(:name =\> ‘Wilma Flint’ , :email =\>  
“removed\_email\_address@domain.invalid” ,:dept =\> 23)  
Customer.create(:name =\> ‘Bert Public’ , :email =\>  
“removed\_email\_address@domain.invalid” ,:balance =\> 12.45)  
barney = Employee.new(:name =\> ‘Barney Rub’ , :email =\>  
“removed\_email\_address@domain.invalid” ,:dept =\> 23)  
barney.boss = wilma  
barney.save!

manager = Person.find\_by\_name(“Wilma Flint” )  
puts manager.class #=\> Manager  
puts manager.email #=\> removed\_email\_address@domain.invalid  
puts manager.dept #=\> 23

customer = Person.find\_by\_name(“Bert Public” )  
puts customer.class #=\> Customer  
puts customer.email #=\> removed\_email\_address@domain.invalid  
puts customer.balance #=\> 12.45

Regards,  
Bas

---

<div class="post-metadata">

**Author:** ![mr\_brownstone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/59ef9b/32.png) [@mr\_brownstone](https://www.ruby-forum.com/u/mr_brownstone)\
**Post date:** [May 29, 2007, 8:03pm UTC](https://www.ruby-forum.com/t/cti-in-activerecord/105325/6 "2007-05-29T20:03:16Z")

</div>

Marcelo J. wrote:

> I search an plugin or gem, but don’t find nothing satisfactory. I  
> believe to be stranger a technology that nails the DRY, have that create  
> you vary equal tables, instead of using inheritance.

Take a peek at [http://clti.rubyforge.org/](http://clti.rubyforge.org/) . It’s still only for  
PostgreSQL though.

–  
Sava C.
