Rails - 使用acts_as_nested_set插件的评论功能 - 删除依赖记录是否会删除销毁数据?

3

我有以下模型:

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)

acts_as_nested嵌套行为是否正常?我本来只期望DELETE FROM COMMENTS where Comment.id=XXXX,但现在所有的内容都在进行中,评论记录正在被破坏。

有人以前见过这种情况吗?

谢谢

更新:用于防止深度嵌套的方法:

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

使用awesome_nested_set存在删除问题。也许你能帮我解决:http://stackoverflow.com/questions/5976085/deletion-of-a-parent-node-but-not-the-children-with-awesome-nested-set - krunal shah
4个回答

3

1
也许可以看一下awesome_nested_set。Collective Idea有一些很棒的gem。不过它已经有一段时间没有更新了,所以可能会有所不同。另外还可以参考这个SO问题/答案 - Michelle Tilley
而且,既然我们已经把这个变成了讨论主题 :P,你甚至可以考虑尝试一个面向文档的数据库,并将你的线程讨论嵌入其中。 - Michelle Tilley
我该如何进行QA以确保删除嵌套项时不会破坏其他非相关项,这正是发生的情况? - AnApprentice
另外,我想防止嵌套过深,所以我在我的模型中添加了这个,这可能是问题吗?(问题已更新) - AnApprentice
这是所有类似的宝石及其最近活动的列表:https://www.ruby-toolbox.com/categories/Active_Record_Nesting - Chloe
显示剩余6条评论

2
“显然,删除节点时它正在尝试维护层次结构,这是 SQL 中常见的问题。
你使用了哪个库?是 Awesome Nested Set 吗?我不确定为什么会导致记录损坏。
你可以在这里阅读有关嵌套集方法的更多信息:”

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

请参考“嵌套集模型”部分和下面的“已删除节点”子部分,了解为什么要以这种方式管理删除操作。
因此,删除语句是正常行为。

1

看起来不太可能,但从未不可能,你使用的宝石不能删除项目并保持正确的嵌套。所以我认为这与你正在做的事情有关。 这也可能与多态关系有关。

您是否尝试移除 ensure_max_nestedset_level 进行测试?然后它是否能够正常工作? 当您删除单个注释时,它是否有效?删除父注释?(在其下有嵌套元素)。 仅当您删除组/线程时才会失败吗?


1

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

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

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

顺便说一句,我使用awesome_nested_set,它是ruby-toolbox推荐的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接