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

Laravel の 多対多リレーション

● Laravel全リレーション

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

これらのうち 多対多 リレーションを操作してみます。

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

とても簡単です。2つのテーブルをつなぐピボットテーブルを作成すればOKです。

・users
・practitioners

というテーブルを多対多でつなぐ時は
テーブル ↓

・user_practitioner

を作成します。( practitioner_user でも良い。 アルファベット順に並べると規則がはっきりして良いですね。単数形 をアンダースコアでつなげます。)
中身は

テーブル「practitioner_user」の構造

id                  (primary key)
user_id             (integer,unsigned)
practitioners_id    (integer,unsigned)

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

    public function up()
    {
        Schema::create('practitioner_user', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('practitioner_id');
            $table->integer('user_id');
        });
    }

● Laravel の 多対多リレーション(belongsToMany)をモデルに設定する

多対多リレーションある意味シンプルです。
これを両方のテーブルに(メソッド名は適宜変更して)定義します。
例)Userモデルに設定

    /**
     * 多対多 リレーション
     * ピボットテーブル「practitioner_user」
     *
     * @return \Illuminate\Database\Eloquent\Relations\belongsToMany
     */
    public function practitioners()
    {
        return $this->belongsToMany('App\Practitioner','practitioner_user');
    }

●多対多リレーションのIDリストを取得する

$model = User::findOrFail($id);
dump( $model->practitioners()->allRelatedIds() );   // (注意)Laravel 5.4以前は getRelatedIds() という名前でした

●多対多リレーションの項目名( カラム名 = practitioner_name )をカンマ区切りで取得する

ユーザ1 , ユーザ2 , ユーザ3 の様な文字列を取得します

$model = User::findOrFail($id);
dump( $model->practitioners()->implode('practitioner_name' , ' , ' ) );

bladeテンプレートに記述するときは以下のようにします。

{!! $consentform->patient->managers->pluck('name')->implode('<br>') !!}

このようにも記述できます。( ↑ と同じです。)

{!! $consentform->patient->managers->implode('name','<br>') !!}

●多対多リレーションの項目名へのリンクを作成する

@php
	$consentform->patient->managers->each(function ($item) {
		$route_manager = route('admin.managers.show', $item->id);
		print <<< DOC_END
			<a href="{$route_manager}" target="_blank">{$item->name}</a><br>
		DOC_END;
	});
@endphp

●多対多リレーションのデータ更新(追加)

$model = User::findOrFail($id);
$model->practitioners()->attach([5,6,7]);    // ピボットテーブルに(すでにあるデータは消さずに)データを追加

●多対多リレーションのデータ更新(書き換え)

$model = User::findOrFail($id);
$model->practitioners()->sync([11,22,33]);    // ピボットテーブルを指定した配列のデータで更新(すでにあるデータを書き換え)
No.1452
06/17 10:28

edit