概要
#mark_for_destruction
を使うと、親要素を保存するタイミングで特定の子モデルをまとめて削除できる。
検証環境は以下の通り。
- Ruby On Rails: 5.2.1
- Ruby: 2.5.1
- MySQL: Ver 14.14 Distrib 5.7.24
利用例
例として、Deck
モデルとCard
モデルが「Deck has many Cards」な関係にあるとする(カードデッキをイメージ)。
親モデル側(ここではDeck)に autosave: true
を設定しておかないといけないので注意。
deck.rb
class Deck
has_many :cards, autosave: true
end
card.rb
class Card
belongs_to :deck
end
次に、1つのDeckに対して複数のCard(card1 ~ card3)を作成する。
deck = Deck.create(name: 'my deck')
deck.cards.create(name: 'card1')
deck.cards.create(name: 'card2')
deck.cards.create(name: 'card3')
ここで、例として card1
と card3
を削除したいとしよう。
対象のCardに対して #mark_for_destruction
を呼び出した上で、Deckを保存する。そうすると、#mark_for_destruction
をつけたCardが全て削除される
deck.cards.first.mark_for_destruction # card1
deck.cards.last.mark_for_destruction # card3
deck.save
# (0.2ms) BEGIN
# Card Destroy (0.4ms) DELETE FROM `cards` WHERE `cards`.`id` = 2
# Card Destroy (0.5ms) DELETE FROM `cards` WHERE `cards`.`id` = 4
# (0.3ms) COMMIT
# => true
deck.cards.count
# => 1