0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Laravel】中間テーブルの値をDateTime型で取得したい

Posted at

目的

多対多のモデルがあり、中間テーブルにはDatetime型のフィールドがあるとします。
たとえば下記のように、ユーザーが複数のスクールに通っており、それぞれのスクールを開始した日時をもっているとき、
名称未設定.png

開始日時をDateTimeで取得し、format()などのメソッドをそのまま使いたいときのモデル定義はどうすればいいかについて、覚書を残します。

foreach($user->schools as $school){
 echo $school->pivot->start_at->format('Y年m月d日'); // Datetimeにキャストされた状態で値を取得したい
}

結論

カスタム中間テーブルモデルを定義し、そこに日付ミューテタを追加します。

手順

1. カスタム中間テーブルを作成する

中間テーブル自体のオリジナルモデルを定義して使用することができます。
Pivotを継承することを忘れないようにしましょう。

SchoolUser.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot; 

class SchoolUser extends Pivot // Pivotを継承する
{
    //
}

2. 日付ミューテタの設定

Eloquentでは、$datesプロパティをセットすることにより、属性値をCarbon(DateTimeの拡張クラス)インスタンスとして取得することができます。
ちなみに、タイムスタンプ(created_atとupdated_at)は自動的にキャストされるようになっています。

<?php

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot;

class SchoolUser extends Pivot
{
    protected $dates = ['start_at']; // 日付ミューテタの設定
}

3. リレーションの設定

おなじみ、各モデルで多対多のリレーションをbelongsToManyで設定します。
このとき、usingメソッドを呼び出すことで、カスタム中間テーブルモデルを使用することができます。

User.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * 役目を所有するユーザー
     */
    public function school()
    {
        return $this->belongsToMany('App\School')
                        ->using('App\SchoolUser') // カスタム中間テーブルの使用
                        ->withPivot([
                            'start_at',
                        ]);
    }
}

以上。

参考

Laravel 7.x Eloquent:リレーション 
Laravel 7.x Eloquent:ミューテタ 

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?