Rails - 注释 wacts_as_nested_set - 当删除从属记录时删除销毁数据

发布于 2024-10-18 17:05:16 字数 3025 浏览 3 评论 0 原文

我有以下模型:

class Group < ActiveRecord::Base
    has_many :threads, :dependent => :destroy

class Thread < ActiveRecord::Base
    has_many :comments, :as => :commentable, :dependent => :destroy

 class Comment < ActiveRecord::Base
    belongs_to :commentable, :polymorphic => true
    acts_as_nested_set

我遇到的问题是当用户删除组时,各种评论都会被破坏或删除。我查看了日志,这就是正在发生的事情:

Comment Load (0.8ms)  SELECT "comments".* FROM "comments" WHERE ("comments".commentable_id = 101 AND "comments".commentable_type = 'Thread') ORDER BY comments.created_at DESC
AREL (0.9ms)  DELETE FROM "comments" WHERE ("comments"."lft" > 649 AND "comments"."rgt" < 650)
AREL (0.4ms)  UPDATE "comments" SET "lft" = ("lft" - 2) WHERE ("lft" > 650)
AREL (0.5ms)  UPDATE "comments" SET "rgt" = ("rgt" - 2) WHERE ("rgt" > 650)
AREL (0.2ms)  DELETE FROM "comments" WHERE ("comments"."id" = 381)
AREL (0.4ms)  DELETE FROM "comments" WHERE ("comments"."lft" > 645 AND "comments"."rgt" < 646)
AREL (0.4ms)  UPDATE "comments" SET "lft" = ("lft" - 2) WHERE ("lft" > 646)
AREL (0.4ms)  UPDATE "comments" SET "rgt" = ("rgt" - 2) WHERE ("rgt" > 646)
AREL (0.2ms)  DELETE FROM "comments" WHERE ("comments"."id" = 380)
AREL (0.3ms)  DELETE FROM "comments" WHERE ("comments"."lft" > 648 AND "comments"."rgt" < 651)
AREL (0.3ms)  UPDATE "comments" SET "lft" = ("lft" - 4) WHERE ("lft" > 651)
AREL (0.3ms)  UPDATE "comments" SET "rgt" = ("rgt" - 4) WHERE ("rgt" > 651)
AREL (0.2ms)  DELETE FROM "comments" WHERE ("comments"."id" = 379)
AREL (0.3ms)  DELETE FROM "comments" WHERE ("comments"."lft" > 644 AND "comments"."rgt" < 647)
AREL (0.4ms)  UPDATE "comments" SET "lft" = ("lft" - 4) WHERE ("lft" > 647)
AREL (0.4ms)  UPDATE "comments" SET "rgt" = ("rgt" - 4) WHERE ("rgt" > 647)
AREL (0.2ms)  DELETE FROM "comments" WHERE ("comments"."id" = 378)
AREL (0.4ms)  DELETE FROM "comments" WHERE ("comments"."lft" > 642 AND "comments"."rgt" < 643)
AREL (0.8ms)  UPDATE "comments" SET "lft" = ("lft" - 2) WHERE ("lft" > 643)
AREL (0.4ms)  UPDATE "comments" SET "rgt" = ("rgt" - 2) WHERE ("rgt" > 643)
AREL (0.2ms)  DELETE FROM "comments" WHERE ("comments"."id" = 377)
AREL (0.7ms)  DELETE FROM "comments" WHERE ("comments"."lft" > 641 AND "comments"."rgt" < 652)
AREL (0.9ms)  UPDATE "comments" SET "lft" = ("lft" - 12) WHERE ("lft" > 652)
AREL (0.9ms)  UPDATE "comments" SET "rgt" = ("rgt" - 12) WHERE ("rgt" > 652)
AREL (0.3ms)  DELETE FROM "comments" WHERE ("comments"."id" = 376)
AREL (0.4ms)  DELETE FROM "threads" WHERE ("threads"."id" = 101)
AREL (0.4ms)  DELETE FROM "groups" WHERE ("groups"."id" = 57)

这是嵌套行为的正常行为吗?我本来期望只是从评论中删除,其中 Comment.id = XXXX。但相反,这一切正在发生,评论记录正在打破。

有人见过这个吗?

谢谢

更新w正在使用什么来防止深层嵌套:

  after_save :ensure_max_nestedset_level
  def ensure_max_nestedset_level
    if self.level > 2
      self.move_to_child_of(parent.parent)
    end
  end

I have the following Models:

class Group < ActiveRecord::Base
    has_many :threads, :dependent => :destroy

class Thread < ActiveRecord::Base
    has_many :comments, :as => :commentable, :dependent => :destroy

 class Comment < ActiveRecord::Base
    belongs_to :commentable, :polymorphic => true
    acts_as_nested_set

The issue I'm having is when a user deletes a group, all kinds of comments are being broken or deleted. I took a look at the logs and this is what's happening:

Comment Load (0.8ms)  SELECT "comments".* FROM "comments" WHERE ("comments".commentable_id = 101 AND "comments".commentable_type = 'Thread') ORDER BY comments.created_at DESC
AREL (0.9ms)  DELETE FROM "comments" WHERE ("comments"."lft" > 649 AND "comments"."rgt" < 650)
AREL (0.4ms)  UPDATE "comments" SET "lft" = ("lft" - 2) WHERE ("lft" > 650)
AREL (0.5ms)  UPDATE "comments" SET "rgt" = ("rgt" - 2) WHERE ("rgt" > 650)
AREL (0.2ms)  DELETE FROM "comments" WHERE ("comments"."id" = 381)
AREL (0.4ms)  DELETE FROM "comments" WHERE ("comments"."lft" > 645 AND "comments"."rgt" < 646)
AREL (0.4ms)  UPDATE "comments" SET "lft" = ("lft" - 2) WHERE ("lft" > 646)
AREL (0.4ms)  UPDATE "comments" SET "rgt" = ("rgt" - 2) WHERE ("rgt" > 646)
AREL (0.2ms)  DELETE FROM "comments" WHERE ("comments"."id" = 380)
AREL (0.3ms)  DELETE FROM "comments" WHERE ("comments"."lft" > 648 AND "comments"."rgt" < 651)
AREL (0.3ms)  UPDATE "comments" SET "lft" = ("lft" - 4) WHERE ("lft" > 651)
AREL (0.3ms)  UPDATE "comments" SET "rgt" = ("rgt" - 4) WHERE ("rgt" > 651)
AREL (0.2ms)  DELETE FROM "comments" WHERE ("comments"."id" = 379)
AREL (0.3ms)  DELETE FROM "comments" WHERE ("comments"."lft" > 644 AND "comments"."rgt" < 647)
AREL (0.4ms)  UPDATE "comments" SET "lft" = ("lft" - 4) WHERE ("lft" > 647)
AREL (0.4ms)  UPDATE "comments" SET "rgt" = ("rgt" - 4) WHERE ("rgt" > 647)
AREL (0.2ms)  DELETE FROM "comments" WHERE ("comments"."id" = 378)
AREL (0.4ms)  DELETE FROM "comments" WHERE ("comments"."lft" > 642 AND "comments"."rgt" < 643)
AREL (0.8ms)  UPDATE "comments" SET "lft" = ("lft" - 2) WHERE ("lft" > 643)
AREL (0.4ms)  UPDATE "comments" SET "rgt" = ("rgt" - 2) WHERE ("rgt" > 643)
AREL (0.2ms)  DELETE FROM "comments" WHERE ("comments"."id" = 377)
AREL (0.7ms)  DELETE FROM "comments" WHERE ("comments"."lft" > 641 AND "comments"."rgt" < 652)
AREL (0.9ms)  UPDATE "comments" SET "lft" = ("lft" - 12) WHERE ("lft" > 652)
AREL (0.9ms)  UPDATE "comments" SET "rgt" = ("rgt" - 12) WHERE ("rgt" > 652)
AREL (0.3ms)  DELETE FROM "comments" WHERE ("comments"."id" = 376)
AREL (0.4ms)  DELETE FROM "threads" WHERE ("threads"."id" = 101)
AREL (0.4ms)  DELETE FROM "groups" WHERE ("groups"."id" = 57)

Is this normal behavior for acts as nested? I would have expect just the DELETE FROM COMMENTS where Comment.id = XXXX. But instead all this is going on and comment records are breaking.

Has anyone seen this before?

Thank you

UPDATE w What is being used to prevent deep nesting:

  after_save :ensure_max_nestedset_level
  def ensure_max_nestedset_level
    if self.level > 2
      self.move_to_child_of(parent.parent)
    end
  end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(4

旧情勿念 2024-10-25 17:05:16

这不应该打破记录。当你删除一个节点时,树必须被修剪。 acts_as_nested_set 中的注释

“添加和删除条目都需要完整的表写入。”

这个 销毁之前的代码当您删除 Comment 记录时,acts_as_nested_set 中的 方法会尝试重新组织表,这是正常行为。

This should not be breaking records. When you delete a node, the tree has to be pruned. The comments in acts_as_nested_set say that

"both adding and removing an entry require a full table write."

The code in this before destroy method in acts_as_nested_set is attempting reorganize the table when you delete the Comment records, and is normal behavior.

简单 2024-10-25 17:05:16

显然,它试图在删除节点时维护层次结构,这是 SQL 中的常见问题。

您使用哪个库?很棒的嵌套集?我不确定为什么它会导致打破记录。

您可以在此处阅读有关嵌套集方法的更多信息:

http://mikehillyer.com /articles/managing-hierarchical-data-in-mysql/

请参阅“嵌套集模型”部分和下面的“已删除节点”小节,了解为什么以这种方式管理删除。

所以删除语句是正常行为。

Well it's apparently trying to maintain the hierarchy when deleting nodes, a common problem in SQL.

Which library are you using? Awesome Nested Set? Why it would result in broken records I'm not sure.

You can read more about the nested set approach here:

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

See the "Nested Set Model" section, and the "Deleted Nodes" sub-section below for why deletions are managed the way they are.

So the delete statements would be normal behavior.

风透绣罗衣 2024-10-25 17:05:16

您使用的 gem 无法删除项目并保持嵌套正确,这似乎不太可能,但绝非不可能。所以恕我直言,这与你正在做的事情有关。
这也可能与多态关系有关。

您是否在删除 ensure_max_nestedset_level 的情况下进行了测试?那行得通吗?
删除一条评论后还能用吗?删除家长评论? (其下有嵌套元素)。
仅当删除组/线程时才会失败吗?

It seems unlikely, but never impossible, that the gem you use is unable to delete items and keep the nestedness correct. So imho it is related to something you are doing.
It might also be related to the polymorphic relation.

Did you test with the ensure_max_nestedset_level removed? Does it work then?
Does it work when you delete a single comment? Delete a parent-comment? (with nested elements under it).
Does it only fail when you delete a group/thread?

为你鎻心 2024-10-25 17:05:16

简单的acts_as_nested_set为评论表中的所有记录创建一个树。我想你应该为每个线程创建一个评论树。例如
acts_as_nested_set:parent_column => :parent_id,:范围=> [:commentable_id,:commentable_type]。

另请注意,默认情况下由 acts_as_nested_set 创建的关联将 :dependent 设置为 :delete_all。因此请确保 :parent_id 设置正确。

通过上述修改,删除组时,仅应删除属于该组(通过线程)的评论。

顺便说一句,我使用 awesome_nested_set activerecord_nesting.html" rel="nofollow">ruby 工具箱。

Simple acts_as_nested_set creates a tree for all records in the comments table. I guess you should create one comment tree per thread. E.g.
acts_as_nested_set :parent_column => :parent_id, :scope => [:commentable_id, :commentable_type].

Notice also that by default associations created by acts_as_nested_set have :dependent set to :delete_all. So make sure that :parent_id is set correctly.

With above modifications when deleting a group, only comments which belong to the group (via threads) should be deleted.

BTW I use awesome_nested_set recommended at ruby-toolbox.

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