What's the best way to destroy both sides of a self-referential association?
In my project, I have a self-referential association.
I have a User model:
class User < ActiveRecord::Base
has_many :relationships, :dependent => :destroy
has_many :peers, :through => :relationships
end
And a Relationship model:
class Relationship < ActiveRecord::Base
belongs_to :user
belongs_to :peer, :class_name => "User"
end
When two users are peers with one another, there are obviously two records in the database.
When one user opts to end a relationship, I'd like this to destroy both records - not just one side of the relationship.
Is there a better way to go about doing this rather than loading the relationship twice in the controller (once for each side开发者_StackOverflow of the relationship)?
Couple of ways this can be done
Firstly is an after delete trigger, this is a pretty controversial way of doing things if you believe in the false promise of database agnosticism, however is one that works - in essence, you look at old.peer_id and old.user_id and then do a delete but reversing the roles. If you want to go down this route, you should consult your database manual as how to implement a trigger.
The second way is an after_destroy
callback where you do a
after_destroy do |record|
other = Relationship.find_by_user_id_and_peer_id(record.peer_id, record.user_id)
other.destroy if other
end
The other - and probably more drastic measure is to rework the model, so that it has a boolean accepted field wherein both sides of the relationship are modelled by one record in the database, there is a constraint on records where (peer_id, user_id) = (user_id, peer_id)
. That way you wont have to worry about deleting both sides, nor having duplicate records.
精彩评论