So I have a friendships table which looks like this:
create_table "friendships", :force => true do |t|
t.integer "user_id"
t.integer "friend_id"
t.integer "status"
end
For each friendship created two rows are inserted, with user_id and friend_id reverted. When a user is deleted the friendship should be deleted also. This code removes one of them:
has_many :friendships, :dependent => :destroy
But that only removes one of the friendships. In my friendship model I have this code:
belongs_to :user
belongs_to :friend, :class_name => "User", :foreign_key => "friend_id"
I also have a custom method for removing friendships which creates a transaction that calls destroy on both the associated objects.
My solution would be to override the destroy method in User and loop through all its friendships and call my remove method on those. This works, but is it an elegant solution? I feel like there could be a nice Rails-way to do this.
Thanks.
The most elegant solution is to have two
has_manyrelations on the User model, one for ‘friends of this user’ (which you’ve already got) and one for ‘users who call this user a friend’. Then set:dependent => :destroyon both of them:This will mean that destroying a User also deletes any friendship records that reference that user as either the user_id or the friend_id.
Removing both the associated objects when breaking a Friendship record seems like a bad idea though – destroying a friendship doesn’t usually mean that both friends cease to exist!