Hi all! I want a simple way to do a "table inheritance" in my DB. For example I have a table "contents" with general attributes for all content types. Something like this: id creator_id created_at modifier_id modified_at ... and so on ... This table describes abstract content object, I'll never want to create it. Then I make article_contents table: id title body content_id <- possible we need foreign key (?) Now, I want an easy way to work with my model ArticleContent to do CRUD operations on it. ArticleContent model must store their attributes in 2 tables: article_contents and contents, but for my business logic level this difference should be clear(as if all attributes are stored in article_content table), and must work well on all database backends. Short version: DRY principle. Don't copy table attributes from contents table to article_contents. P.S. Sorry for my English.
on 2005-11-25 10:49
on 2005-11-25 17:43
Hi Vlad, It sounds like you want class table inheritance, which there's no out of the box solution for yet (someone correct me if I'm wrong). I've been dealing with this all week and found something that seems to work in my tests. I have similar table setups, one being a parent content table and another being content_news. content_news contains a FK (content_news.content_id) that points to the content.id col. I found that I can make changes on a ContentNews object and have them persist to the proper fields in the content table. However, save and new do not seem to work. Here's my AR object: class Content < ActiveRecord::Base set_table_name "content" set_sequence_name "content_id_seq" has_one :content_type, :foreign_key => "id" end class ContentNews < ActiveRecord::Base set_table_name "content_news" set_primary_key "content_id" belongs_to :content, :dependent => true, :foreign_key => "id" # Makes sure the parent Content object is also deleted def after_destroy if self.id != nil : content.destroy end end # Makes sure a parent Content news is created and gives out its id def before_save if self.id == nil : self.id=content.id end end end While the above requires more typing, it does seem to work (so far). Ideally it would be nice to just automagically have Rails do this for me, but again, it doesn't seem that CTI support is in the code base yet (here's the ticket #: http://dev.rubyonrails.org/ticket/600 ) I think in the ticket there was talk about being able to also look at, say, Content attributes and then be able to get a hold of the relevant child object - this may be tricky if you have multiple child object types, not sure as I'm still somewhat new to Ruby/Rails. For my case, I always go child -> parent, so that's not really an issue for me now. If you (or anyone) sees any issues with the above, please let me know. I might, some day, switch to STI, but honestly in my case where we'll keep adding different content types with their own attributes (could be a dozen or more at some point), it doesn't make sense for me to use STI and keep adding columns on to one table - depending on the required attributes, said table could be *really* big. The Agile Web Development with Rails book has a few paragraph blurbs about what you could try if STI doesn't work for you (pg. 266). But, it's just that, a quick paragraph, so there's no real in-depth like the other stuff. If you do find a different, more generic way than I have mentioned, please share it with the list. Thanks. -jason
on 2005-11-25 18:16
On 11/25/05, Vlad Zarakovsky <email@example.com> wrote: > Hi all! ... > Short version: DRY principle. Don't copy table attributes from contents > table to article_contents. > > P.S. Sorry for my English. > BTW, your English was very good. I got it on the first reading. I, too, am looking for a similar solution, because of the DRY principle. Ed