人気のPHP WEBアプリケーションフレームワークLaravelのTipsを記録していきます

Laravel で 複数のモデルに対応した多対多のポリモーフィック・リレーションを扱う

● Laravel全リレーション

1対1
1対多
多対多
Has Many Through
1対1(ポリモーフィック)
1対多(ポリモーフィック)
多対多(ポリモーフィック)

これらのうち 多対多ポリモーフィック・リレーションを操作してみます。

● Laravel の 多対多リレーションのDB構造

「チームデータ」を複数のテーブルにつける。のをイメージするととても簡単です。 まずは2つのテーブルをつなぐピボットテーブルを作成すればOKです。 さらに、ポリモーフィック・リレーションの場合はテーブル名(テーブルのクラス名)も保存します。 (これにより「チームデータ」は色々なテーブルと多対多リレーションさせることができます。)

・posts(テキスト投稿データ)
    id - integer
    name - string

・videos(ビデオ投稿データ)
    id - integer
    name - string

・teams(チームデータ)
    id - integer
    name - string

というテーブルを多対多ポリモーフィック・リレーションでつなぐ時は
テーブル ↓

・teamaccessible
    team_id - integer
    teamaccessible_id - integer
    model_name - string

を作成します。

マイグレーションファイルの作成

php artisan make:migration create_teamaccessible_table

マイグレーションファイルの up() メソッドは次のようになります。

    public function up()
    {
        Schema::create('teamaccessibles', function (Blueprint $table) {
            $table->integer('team_id');
            $table->integer('teamaccessible_id');
            $table->string('teamaccessible_type');
        });
    }

● Laravel の 多対多ポリモーフィック・リレーション(morphToMany)をモデルに設定する

多対多リレーションの時は belongsToMany でしたが、 多対多ポリモーフィック・リレーションの場合は morphToMany を設定します。

これを トレイトに 定義して、複数のテーブルから使用します。

例) app/TeamAccessibleTrait.php に設定

    /**
     * ● 多対多ポリモーフィック・リレーション
     *
     * ->teams でモデルに紐づけられたチーム一覧を取得します。
     *
     * ピボットテーブル「teamaccessible」
     *
     * @return \Illuminate\Database\Eloquent\Relations\morphToMany
     */
    public function teams()
    {
        return $this->morphToMany('App\Team', 'teamaccessible');
    }

モデルでトレイトを呼び出します

    use \App\OnlyTeamAccessibleTrait;       // チームでアクセス可能なデータに限定する
No.1718
06/26 23:28

edit