Rails - 注释 wacts_as_nested_set - 当删除从属记录时删除销毁数据
我有以下模型:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这不应该打破记录。当你删除一个节点时,树必须被修剪。
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 thatThe code in this
before destroy
method inacts_as_nested_set
is attempting reorganize the table when you delete theComment
records, and is normal behavior.显然,它试图在删除节点时维护层次结构,这是 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.
您使用的 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?
简单的
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.