摧毁自我参照关联双方的最佳方法是什么?

发布于 2024-10-11 05:25:49 字数 501 浏览 5 评论 0原文

在我的项目中,我有一个自我参照关联。

我有一个用户模型:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

只等公子 2024-10-18 05:25:49

有几种方法可以做到这一点

首先是删除后触发器,如果您相信数据库不可知论的错误承诺,这是一种非常有争议的做事方式,但本质上是一种有效的方式,您查看 old.peer_id 和 old.user_id,然后执行删除但反转角色。如果您想走这条路,您应该查阅数据库手册以了解如何实现触发器。

第二种方法是 after_destroy callback ,您可以在其中执行

after_destroy do |record| 
  other = Relationship.find_by_user_id_and_peer_id(record.peer_id, record.user_id)
  other.destroy if other
end

另一个 - 可能更激烈的措施是重新设计模型,以便它有一个布尔接受字段,其中双方由于关系的一部分由数据库中的一条记录建模,因此对 (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 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文