ポリモーフィックリレーションでリレーション先のモデルが存在しないものは取得対象外にしたい
関連モデルが削除されているデータは取得対象外にしたい。
そんなときあるよねー!
例)
- Aさんがコメントしました。
- Aさんが
記事X
についてコメントしました。 - Aさんが
記事Y
についてコメントしました。 - Bさんが
記事X
についてコメントしました。 - Aさんが
ビデオZ
についてコメントしました。
コメントの一覧を取得したい。
ただし記事Xが削除されたので、2,4は除く。
->where(function ($query) {
// そもそも関連モデルのないコメントは取得したい(1のこと)
$query->whereNull('commentable_id');
// 関連モデルIDがあり、関連モデルが生きているものを取得(3と5)
$query->orWhereHasMorph(
'commentable',
[Post::class, Video::class],
function ($query) {
$query->whereNotNull('commentable_id');
}
);
})
余談(commentable_typeに登録する値)
ポリモーフィックタイプはデフォルトでモデル名が登録されるが、
- 将来的にモデル名(ディレクトリ)が変更されたり
- CQRSで同じモデルを複数クラス定義する可能性もあるので
文字列定義してそれを使用するのがオススメ。
(App\Models\Post
ではなく post
で登録しておこう的な話)
const.php
'POLYMORPHIC_TYPE' => [
'POST' => 'post',
'VIDEO' => 'video',
],
Commentモデル
public function commentable()
{
Relation::morphMap([
config('const.POLYMORPHIC_TYPE.POST') => 'App\Services\GetCommentList\Query\Models\Post',
config('const.POLYMORPHIC_TYPE.VIDEO') => 'App\Services\GetCommentList\Query\Models\Video',
]);
return $this->morphTo();
}