関連モデルが削除されているデータは取得対象外にしたい。
そんなときあるよねー!

例)

  1. Aさんがコメントしました。
  2. Aさんが記事Xについてコメントしました。
  3. Aさんが記事Yについてコメントしました。
  4. Bさんが記事Xについてコメントしました。
  5. 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();
}

Tags:

Updated: