Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
15
Help us understand the problem. What is going on with this article?
@yosida001

[メモ][Laravel]Pivotモデルについて一瞬つまづいたポイントメモ

More than 3 years have passed since last update.

Pivotモデルについて一瞬つまづいたポイントメモ

この記事はPivotモデルを利用した多対多構成が、普通にドキュメントを読んでもわかりづらかったので自分的にわかりやすくしたメモです。
想定構成はPHP7 laravel5.5となっております。

なお、基本的に以下のページを参照しています。
おそらく躓きそうなことの8割は以下のページを見れば解決するかと思います。
Laravel 5.5 Eloquent:リレーション
Pivot tables and many-to-many relationships

Pivotテーブルの名称を特殊なものにしたい。

pivotテーブルの名称をLaravel標準のlogal_forginではなく、自分で作成した名称のものにしたいとき、belongsToManyの第二引数にテーブル名を与えると行うことができる。

public function users()
{
    return $this->belongsToMany('App\Role', 'role_user');
}

Eloquentではクラスのプライベート変数にテーブル名を宣言することができるため、以下のようにやりたくなるが、それは正しくない。

Role.php
<?php
namespace App
use Illuminate\Database\Eloquent\Model;

class Role extends Model {
    public function users() {
         return $this->belongsToMany('App\Role')->using('App\RoleUser');
    }
}
RoleUser.php
<?php
namespace App
use Illuminate\Database\Eloquent\Relations\Pivot;

class RoleUser extends Pivot {
    protected $table = "role_user";
}

Pivotモデルは以下のように呼び出す場合にデータが格納されるモデルの指定であり、取得系には関係がない。
たとえPivotモデルでテーブル名を指定してあっても、実際に呼び出しているEloquentモデル側で指定してあるDBテーブル名が間違えていれば容赦なく呼び出しに失敗する。
pivotモデルを利用したテーブルの指定方法があったら教えてください。複数個所で同一テーブル名指定したくないです……

ActionController.php
$roles = Role::find(1)->users;
foreach ($users as $user) {
    debug($user->pivot);
}

また、たとえpivotテーブルをモデルとして指定してあっても、pivotテーブル内の他のデータを取得するためにはリレーション指定の時点で指定していなければ呼び出すことができない。

Role.php
<?php
namespace App
use Illuminate\Database\Eloquent\Model;

class Role extends Model {
    public function users() {
         return $this->belongsToMany('App\Role', 'role_user')->using('App\RoleUser');
    }
}
ActionController.php

$roles = Role::find(1)->users;
foreach ($users as $user) {
    debug($user->pivot->flag); //null
}

以下のようにすれば呼び出せる。

Role.php
<?php
namespace App
use Illuminate\Database\Eloquent\Model;

class Role extends Model {
    public function users() {
         return $this->belongsToMany('App\Role', 'role_user')->using('App\RoleUser')->withPivot("flag");
    }
}
ActionController.php

$roles = Role::find(1)->users;
foreach ($users as $user) {
    debug($user->pivot->flag); //1
}

しかしこのように指定した場合、べつにPivotモデルを指定していなくても値は同様に呼び出すことができる。

Role.php
<?php
namespace App
use Illuminate\Database\Eloquent\Model;

class Role extends Model {
    public function users() {
         return $this->belongsToMany('App\Role', 'role_user')->withPivot("flag");
    }
}
ActionController.php

$roles = Role::find(1)->users;
foreach ($users as $user) {
    debug($user->pivot->flag); //1
}

結論

結局Pivotテーブルを使う意味はあるのだろうか?
おそらく複雑な更新などを行いたいときに、モデル内に関数を増やしたい……などの時に使うことができるのかもしれないが、多対多構成用の更新メソッドも簡単なのはLaravel標準でついているため、そうとう複雑ではない限りは使うことはないように思う。(個人の感想です)
少なくとも「同じテーブル名を複数箇所で宣言したくない」という程度の用途には向かないことが判明したため、涙を呑んでモデルを削除することにする。

15
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
yosida001
社内情シス。PHPer。Laravel-Frameworkを中心としてやってます。 業務上調べることの多い項目等についてメモを残すためにはじめました。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
15
Help us understand the problem. What is going on with this article?