LoginSignup
0
0

アクセサ、ミューテタでlaravelのモデルを賢くする。

Posted at

今までlaravelのモデルをDBバインドにしか使ってませんでした。
アクセサ、ミューテタで結構賢くすることができたのでメモします。

アクセサ

モデルの値を取得する時にひと手間加えてくれる。

例)created_atを表示

    $model->created_at; // 2024-04-17T10:02:20.000000Z
    
    $model->created_at->format('Y/m/d H:i:s'); // 2024/04/17 19:02:20

モデルにアクセサを設定すると↓

Models\user.php
use Illuminate\Database\Eloquent\Casts\Attribute; // 忘れずに

    //アクセサ
    public function createdAt() {
        return Attribute::make(
            get: function () {
                return $this->created_at->format('Y/m/d H:i:s');
            }
        );
    }

こうなります↓

呼び出し側
    $model->created_at; // 2024/04/17 19:02:20

モデルではキャメルcreatedAt()なのに、
呼び出す時はスネークcreated_atでもオッケーです🙆‍♀️

■ 関数名は変えてもオッケーです。

Models\user.php
    //アクセサ
    public function createdDateTime() {
        return Attribute::make(
            get: function () {
                return $this->created_at->format('Y/m/d H:i:s');
            }
        );
    }
呼び出し側
    $model->created_datetime; // 2024/04/17 19:02:20

■ 他のカラムを参照する場合。
例)is_member, is_admin, is_gestフラグを配列にする。

Models\user.php
    protected function authorities()
    {
        return Attribute::make(
            //アクセサ
            get: fn ($value, $attributes) => array_filter([
                $attributes['is_member'] ? 'member' : '',
                $attributes['is_admin'] ? 'admin' : '',
                $attributes['is_gest'] ? 'gest' : '',
            ]),
        );
    }
呼び出し側
    $model->authorities; // ['member', 'admin', 'gest']

ミューテタ

モデルの値を格納する時にひと手間加えてくれる。
アクセサと逆の操作。

Models\user.php
    protected function authorities()
    {
        return Attribute::make(
            // ミューテタ
            set: fn ($value) => [
                'is_member' => in_array('member', $value),
                'is_admin' => in_array('admin', $value),
                'is_gest' => in_array('gest', $value),
            ],
        );
    }

モデルに値を入れるとミューテタを通る。

呼び出し側
    $model->authorities = ['member', 'admin'];
    // $model->is_member  1
    // $model->is_admin  1
    // $model->is_gest  0

■ アクセサ、ミューテタを両方設定する時はこう

Models\user.php
    protected function authorities():
    {
        return Attribute::make(
            //アクセサ
            get: fn ($value, $attributes) => array_filter([
                $attributes['is_member'] ? 'member' : '',
                $attributes['is_admin'] ? 'admin' : '',
                $attributes['is_gest'] ? 'gest' : '',
            ]),
            // ミューテタ
            set: fn ($value) => [
                'is_member' => in_array('member', $value),
                'is_admin' => in_array('admin', $value),
                'is_gest' => in_array('gest', $value),
            ],
        );
    }
Models\user.php
    protected function isMember()
    {
        return Attribute::make(
            get: fn ($value) => $value ? 'member' : '',
            set: fn ($value) => $value ? 1 : 0,
        );
    }

キャスト cast

アクセサ、ミューテタを設定するほどではないが型は守って欲しい時。

Models\user.php
   protected $casts = [
        'is_member' => 'boolean',
        'is_admin' => 'boolean',
        'is_gest' => 'boolean',
    ];
呼び出し側
    $model->is_member = '猫'; // 1
    $model->is_admin = 1111; // 1
    $model->is_gest = null; // 0

入れても出してもその型にキャストしてくれる。

トレイト trait

アクセサ、ミューテタ、その他の機能を切り出して共通化する。
こうやって新しいクラスを作っておくと。

App\Traits\DateTrait.php
<?php

namespace App\Traits;

use Illuminate\Database\Eloquent\Casts\Attribute;

trait DateTrait {
    public function createdAtAsDate(){
        return Attribute::make(
            get: function () {
                return $this->created_at->format('Y/m/d');
            }
        );
    }
}

これだけで使える。
(SoftDeletes、HasFactoryなどと同じ)

Models\user.php
// use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Illuminate\Database\Eloquent\SoftDeletes;
use App\Traits\DateTrait;

class User extends Model
{
    // use HasFactory;
    // use SoftDeletes;
    use DateTrait;
    ...
呼び出し側
    $model->createdAtAsDate; // 2024/04/17

いかがだったでしょうか。

・アクセサ
・ミューテタ
・キャスト
・トレイト
を使ってモデルを賢くさせましょう!

0
0
1

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