Does anyone has experience implementing single table inheritance. Does it really work? This is my situation, I trying to have a base table call category. then I have a model call TodoCategory to inherit category, HelpDeskCategory to inherit category. After that I have TodoItem model that have a field call TodoCategory_id, the story goes on. I am having a really hard time to get it work. Dose this single table inheritance really works? or do I miss out something here.
Paul, This is my situation, I trying to have a base table call category. then I> have a model call TodoCategory to inherit category, HelpDeskCategory to > inherit category.I''m using it almost the exact same way. I have a User table and 3 models that associate with it: User, Caregiver and Admin. class User < ActiveRecord::Base class Admin < User class CareGiver < User Now, the one thing that gave me some problems were the requires. I don''t know if they''re still relevant or not, but I had to put require ''admin'' and require ''caregiver'' lines in the User model. After that I have TodoItem model that have a field call TodoCategory_id,> the story goes on. I am having a really hard time to get it work. >The way that Rails handles STI is via a type column in the table that is populated with the type of object you want that record to reference. So, in your case, maybe a little something a-like this: class Category < ActiveRecord::Base class TodoCategory < Category class HelpDeskCategory < Category And in your Category table, remove the TodoCategory_id column and replace it with type. For every ToDoCategory row, type must contain TodoCategory. The same holds for HelpDeskCategory. Hope that works, or at least points you in the right direction. -- Mando _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Interesting. This introduces a nasty redundancy. The way I have always handled STI is via something such as: people ----------- id first_name last_name users --------- person_id email active user_passwords ----------------------- user_id password I haven''t yet implemented STI in Rails, but am currently trying to decide whether it fits a very robust publishing tool I''ve had designed for some time now and have partially implemented in other languages. I imagine the model classes might look something like: class Person < ActiveRecord::Base end class User < Person set_primary_key "person_id" end I imagine this means I''ll have to manually join the tables, which I suppose is fine. It''s far better than redundancy, IMO, and gives me a chance to optimize my queries for my specific RDBMS. It is unfortunate if the "type" column approach is the only way STI will be supported in Rails, though. -tj On Aug 5, 2005, at 9:19 AM, Mando Escamilla wrote:> For every ToDoCategory row, type must contain TodoCategory. The > same holds for HelpDeskCategory.
Toby,> The way I have always handled STI is via something such as: > > people > ----------- > id > first_name > last_name > > users > --------- > person_id > email > activeActually, this isn''t Single Table Inheritance at all... you are describing a different O-R mapping pattern. There are several different patterns for mapping the inheritance hierarchy of classes in an object oriented language onto a relational database. ActiveRecord uses Single Table Inheritance. What you describe in your example is closer to the Class Table Inheritance pattern. There are advantages and disadvantages of both. For more info, look at the relevant sections in chapter 12 of _Patterns of Enterprise Application Architecture_ by Martin Fowler. Ken
You''re right -- I used the wrong name/concept. Woops! I have and know the Fowler book, but mixed up my ideas when writing on my commute. :( On Aug 5, 2005, at 1:38 PM, Ken Kunz wrote:> Toby, > > >> The way I have always handled STI is via something such as: >> >> people >> ----------- >> id >> first_name >> last_name >> >> users >> --------- >> person_id >> email >> active >> > > Actually, this isn''t Single Table Inheritance at all... you are > describing a different O-R mapping pattern. > > There are several different patterns for mapping the inheritance > hierarchy of classes in an object oriented language onto a relational > database. ActiveRecord uses Single Table Inheritance. What you > describe in your example is closer to the Class Table Inheritance > pattern. There are advantages and disadvantages of both. For more > info, look at the relevant sections in chapter 12 of _Patterns of > Enterprise Application Architecture_ by Martin Fowler. > > Ken > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
I am using STI to model organizations (department < organization, company < organization) so I can use Composite Pattern. I am using migrations to do the DDL for MySql class CreateCompany < ActiveRecord::Migration def self.up create_table :organizations do |t| t.column :name, :string t.column :label, :string t.column :phone, :string t.column :fax, :string t.column :address, :string t.column :type, :string t.column :position, :integer t.column :parent_id, :integer t.column :costcode, :string end end def self.down drop_table :organizations end end ------------ here''s my organization.rb file class Organization < ActiveRecord::Base validates_presence_of :name end class Company < Organization has_many :departments end class Department < Organization before_save :copy_parent acts_as_tree belongs_to :company, :foreign_key => ''company_id'' validates_presence_of :company_id def copy_parent self.type = self.parent.type if self.parent self.company = self.parent.company if self.parent end end class FaaDepartment < Department validates_presence_of :costcode validates_uniqueness_of :costcode end ------------------------ What I want to happen is if a company has a root department, every department that is created from that root with the :children method inherits the same company and type of the parent department company = Company.new(:name => ''FAA'') company.save root = company.departments.create(:name => ''ANI'', :type => ''FaaDepartment'') now I want root.children.create(:name => ''ANI-2'') to inherit the company_id and the type from its parent but copy_parent from above doesn''t work. Any suggestions? Thanks in advance, dom