依赖性破坏不会破坏依赖性

时间:2013-12-03 21:07:50

标签: ruby-on-rails activerecord

我有以下型号:

class Article < ActiveRecord::Base
    has_many :comments, :as => :subject, :dependent => :destroy
    has_many :deleted_comments, :as => :subject, :dependent => :destroy
end

class DeletedComment < ActiveRecord::Base
    belongs_to :subject, :polymorphic => true
end

class Comment < ActiveRecord::Base
    belongs_to :subject, :polymorphic => true
    before_destroy :create_deleted_comment

    def create_deleted_comment
        DeletedComment.create!(....)
    end
end

在我的数据库中,我有很多DeletedComment对象,其中主题为零。 DeletedComment(和Comment)模型存储:article_id,对于主题为nil的那些,Article.find(deleted_comment.article_id)引发ActiveRecord :: RecordNotFound错误。

是否存在:dependent =&gt; :destroy会破坏父记录但是保持依赖性没有变化?

在某些情况下,当我删除文章时,是否有可能在评论之前销毁deleted_comments?当注释被销毁时,deleted_comments被创建而不被销毁(因为ActiveRecord已经检查了依赖的deleted_comment并试图销毁任何依赖项)?

1 个答案:

答案 0 :(得分:1)

根据official documentation

将多态关联与单表继承(STI)结合使用有点棘手。为了使关联按预期工作,请确保将STI模型的基本模型存储在多态关联的类型列中。要继续上面的资产示例,假设有一些访客帖子和成员帖子使用了STI的posts表。在这种情况下,posts表中必须有一个类型列。

class Asset < ActiveRecord::Base
  belongs_to :attachable, polymorphic: true

  def attachable_type=(sType)
     super(sType.to_s.classify.constantize.base_class.to_s)
  end
end

class Post < ActiveRecord::Base
  # because we store "Post" in attachable_type now dependent: :destroy will work
  has_many :assets, as: :attachable, dependent: :destroy
end

class GuestPost < Post
end

class MemberPost < Post
end

我想你可以使用考试并做类似的事情:

class Article < ActiveRecord::Base
  # for deletion only
  has_many :abstract_comments, :as => :subject, :dependent => :destroy

  # for 'manual' access/edition 
  has_many :comments,         :as => :subject
  has_many :deleted_comments, :as => :subject
end

class AbstractComment < ActiveRecord::Base
  belongs_to :subject, :polymorphic => true

  def attachable_type=(sType)
    super(sType.to_s.classify.constantize.base_class.to_s)
  end
end

class DeletedComment < AbstractComment
end

class Comment < AbstractComment
  before_destroy :create_deleted_comment

  def create_deleted_comment
    DeletedComment.create!(....)
  end
end