投稿の経緯
Twitter、FbのようなSNSを作成中のことです。
投稿機能に削除ボタンを付けたのですが…投稿が消せない!!
もっと細かく言うと、ただの投稿は消せる。
投稿に写真を載せたり(postモデルとimageモデルで分けている場合に限る)
投稿にコメントをされたりすると消せなくなる。。
【本日の登場人物】
(親)postモデル →投稿を保存するモデル
(子)imageモデル →投稿に紐づく画像を保存するモデル
(子)commentモデル →投稿に対するコメントを保存するモデル
つまり、postモデルにネストしている**子モデル(imageモデル、commentモデル)**に値が入るとpostレコードを削除できなくなってしまう訳ですね。
実際のコードを見てみましょう。
実際のコード
class Post < ApplicationRecord
belongs_to :user
has_many :comments
has_many :images
end
何の変哲もないpostモデルのアソシエーションですね。
ただ、このままだと、子モデルに値が入ると親モデルが消せなくなります。
なぜなら、親が消えてしまったら、子の親がいなくなってしまうから。。当たり前ですね笑
つまり、親を削除した時に、子も一緒に削除される設定をしてしまえばいいんです。
解決策
モデルで**「dependent: :destroy」**を設定してあげましょう。
dependent…翻訳すると「依存」ですね。イメージ湧きやすいかと思います。
これをアソシエーションの時に設定されたモデルは、そのクラスが削除されると、一緒に削除されるようになります。
何言ってるかわからないですね、実際に下に書いてみます。
解決後のコード
class Post < ApplicationRecord
belongs_to :user
has_many :comments, dependent: :destroy
has_many :images, dependent: :destroy
end
何となくわかりましたかね?
Postクラス で imageモデル と commentモデルに設定していますね。
postモデル(投稿)が削除されるとアソシエーションでdependent: :destroyを設定されたモデル(画像、コメント)も一緒に削除される訳ですね。
注意点
これに関して注意してもらいたいことがあります。
実はこのdependent: :destroyって子モデルを削除するための設定じゃないんです。
アソシエーションを削除するための設定なんです。
例えば、commentモデルに以下のとおり記載してみます。
belongs_to :post, dependent: :destroy
こうなってしまうと、コメントを削除したら投稿まで削除されてしまいます。
もう一度いいます。
アソシエーションの時に設定されたモデルは、そのクラスが削除されると、一緒に削除されるようになります。
まとめ
今回も私の拙い説明を最後まで読んでいただきありがとうございました。
間違いや補足がありましたらコメントいただけると嬉しいです。
どんどはれ。