摧毁自我参照关联双方的最佳方法是什么?
在我的项目中,我有一个自我参照关联。
我有一个用户模型:
class User < ActiveRecord::Base
has_many :relationships, :dependent => :destroy
has_many :peers, :through => :relationships
end
和一个关系模型:
class Relationship < ActiveRecord::Base
belongs_to :user
belongs_to :peer, :class_name => "User"
end
当两个用户彼此对等时,数据库中显然有两条记录。
当一个用户选择结束关系时,我希望这会销毁两条记录 - 而不仅仅是关系的一侧。
有没有更好的方法来执行此操作,而不是在控制器中加载关系两次(关系的每一方一次)?
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 of the relationship)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有几种方法可以做到这一点
首先是删除后触发器,如果您相信数据库不可知论的错误承诺,这是一种非常有争议的做事方式,但本质上是一种有效的方式,您查看 old.peer_id 和 old.user_id,然后执行删除但反转角色。如果您想走这条路,您应该查阅数据库手册以了解如何实现触发器。
第二种方法是
after_destroy
callback ,您可以在其中执行另一个 - 可能更激烈的措施是重新设计模型,以便它有一个布尔接受字段,其中双方由于关系的一部分由数据库中的一条记录建模,因此对
(peer_id, user_id) = (user_id, peer_id)
的记录存在约束。这样您就不必担心删除两侧,也不必担心重复记录。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 aThe 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.