Rails - Комментарии w act_as_nested_set - при удалении зависимой записи удаляется уничтожение данных - PullRequest
3 голосов
/ 21 февраля 2011

У меня есть следующие модели:

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

Ответы [ 4 ]

3 голосов
/ 25 февраля 2011

Это не должно быть бить рекорды.Когда вы удаляете узел, дерево должно быть сокращено. Комментарии в acts_as_nested_set говорят, что

"для добавления и удаления записи требуется полная запись таблицы."

Код в этот before destroy метод в acts_as_nested_set пытается реорганизовать таблицу при удалении записей Comment, и это нормальное поведение.

2 голосов
/ 25 февраля 2011

Ну, очевидно, он пытается поддерживать иерархию при удалении узлов, что является распространенной проблемой в SQL.

Какую библиотеку вы используете? Высокий Вложенный Набор? Почему это может привести к испорченным записям, я не уверен.

Подробнее о подходе с вложенным множеством можно прочитать здесь:

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

См. Раздел «Модель вложенного набора» и подраздел «Удаленные узлы» ниже, чтобы узнать, почему удаления управляются так, как они есть.

Таким образом, операторы удаления будут нормальным поведением.

1 голос
/ 03 марта 2011

Простой 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 .

1 голос
/ 03 марта 2011

Кажется маловероятным, но никогда невозможным, что используемый вами драгоценный камень не может удалять предметы и сохранять правильность вложенности.Имхо, это связано с чем-то, что вы делаете.Это также может быть связано с полиморфным отношением.

Тестировали ли вы с удаленным ensure_max_nestedset_level?Это работает тогда?Работает ли это, когда вы удаляете один комментарий?Удалить родительский комментарий?(с вложенными элементами под ним).Сбой только при удалении группы / потока?

...