web-dev-qa-db-ja.com

Ruby ActiveRecordモデルのカスケード削除?

私はrubyonrails.orgのスクリーンキャストをフォローしていました(ブログを作成しています)。

私は次のモデルを持っています:

comment.rb

class Comment < ActiveRecord::Base
    belongs_to :post
    validates_presence_of :body # I added this
end

post.rb

class Post < ActiveRecord::Base
    validates_presence_of :body, :title
    has_many :comments
end

モデル間の関係は正常に機能しますが、1つだけ例外があります。投稿レコードを削除すると、RoRによってすべての関連するコメントレコードが削除されると思います。 ActiveRecordsはデータベースに依存しないため、外部キー、リレーション、ON DELETE、ON UPDATEステートメントを作成する組み込みの方法はありません。それで、これを達成する方法はありますか(おそらくRoR自体が関連するコメントの削除を処理できるでしょうか?)

48
Jakub Lédl

はい。 Railsのモデルの関連付けでは、:dependentオプションを指定できます。これは、次の3つの形式のいずれかになります。

  • :destroy/:destroy_all関連付けられたオブジェクトは、destroyメソッドを呼び出すことにより、このオブジェクトとともに破棄されます
  • :delete/:delete_all:destroyメソッドを呼び出さずに、関連するすべてのオブジェクトが即座に破棄されます
  • :nullifyNULLコールバックを呼び出さずに、すべての関連オブジェクトの外部キーがsaveに設定されます

:dependent関連付けが設定されている場合、:has_many X, :through => Yオプションは無視されることに注意してください。

したがって、例として、各コメントのdestroyメソッドを呼び出さずに、投稿自体が削除されたときに、関連するすべてのコメントを削除するように選択することができます。これは次のようになります。

class Post < ActiveRecord::Base
  validates_presence_of :body, :title
  has_many :comments, :dependent => :delete_all
end

Rails 4の更新:

Rails 4では、:destroyではなく:destroy_allを使用する必要があります。

:destroy_allを使用すると、例外が発生します。

:dependentオプションは[:destroy、:delete_all、:nullify、:restrict_with_error、:restrict_with_exception]のいずれかである必要があります

85
John Topley