views:

372

answers:

2

I'm porting some functionality to Rails, and I'm working with an existing table which is for comments.

Basically, there are two types of comments - profile comments (photo_id column is null) and photo comments (photo_id column is set to photo's ID)

I got single table inheritance working just fine by adding a type field to the table, but I'm wondering if there's a way to get my single table inheritance working without the type field. According to the Rails API documentation, "If you don‘t have a type column defined in your table, single-table inheritance won‘t be triggered. In that case, it‘ll work just like normal subclasses with no special magic for differentiating between them or reloading the right type with find."

I'm wondering if there's a way that I can customize my models to determine type based on photo_id being nil or having an integer value, rather than using the database column (which I'd rather not add if I don't have to.) Any ideas?

A: 

I suspect you cannot do this trivially. However, one possibility is to trick active record into using a view rather than a table, and write some database functions to set this magic attribute based on which id is set.

However, in the end, I suspect it would be far, far easier to just add the column.

Michael Graff
+1  A: 

If comments models doesn't differ much, I wouldn't bother with single table inheritance at all. Just add:

# to Comment model
belongs_to :photo
belongs_to :profile

# to Profile model
has_many :comments

# to Photo model
has_many :comments

Then:

@photo.comments # will return comments associated with photos
@profile.comments # will return comments associated with profiles

There may be problem if you had both photo_id and profile_id set (I suppose it may happen when you comment a photo that is associated with profile), so you can change in Profile model:

has_many :comments, :conditions => "photo_id is not null"

Another approach (I think better) it to you polymorphic associations but you will need to modify you sql tables.

klew
Thanks! This works perfectly for my purposes.I actually initially went down this approach but got mixed up because I do indeed have both photo_id and profile_id set for some rows, and I wasn't aware of the `:conditions` option. Thanks again!
Coomer