How to destroy a record with has_many, :dependent => :destroy

AnApprentice picture AnApprentice · Nov 1, 2010 · Viewed 10.8k times · Source

I've built a Rail 3 AuditLog with the help of a few plugins, that store data in an AuditLog Table with the following fields for identification (feeded_id, feeded_type)

So in my case, I have a photoalbum that has_many photos.

class PhotoAlbum < ActiveRecord::Base
has_many :photos, :dependent => :destroy

when I delete a photoalbum (id=2) this works very well to delete all associated photos, but it doesn't delete items from the AuditLog that are like this: (feeded_id = 2, feeded_type = PhotoAlbum)

Given that the AuditLog table doesn't have a "photo_album_id" column, and can't, is there a way to setup a dependent > Destory with Rails to delete all associated items in teh AuditLog when a PhotoAlbum is deleted?

Thanks, I know this one's a little more complicated than most. Thanks for reading through it!

Answer

Brett Bender picture Brett Bender · Nov 1, 2010

I think what you are looking for is the combination of

belongs_to :feeded, :polymorphic => true

in your Audit log class and

has_many :logs, :as => :feeded, :dependent => :destroy

in your PhotoAlbum class.

If you do not have a class to represent your audit log, you should be able to add the belongs_to to the existing class (in your plugins perhaps?).

I'm not 100% sure about the :as => :feeded option, you will have to name that symbol correctly and I am not sure what ActiveRecord will expect, but the belongs_to relationship will look for feeded_id and feeded_type, so when the 'parent' object is a PhotoAlbum it will join correctly on photo_album.id = audit_logs.feeded_id AND audit_logs.feeded_type = 'PhotoAlbum'. Since this doesn't require any changes to your database, all your existing code should continue to work.

You can read up on the options for associations here.