LoginSignup
2
0

More than 1 year has passed since last update.

【Larvel】アクセサとミューテタ ~DBのデータ加工・独自プロパティの定義を行う~

Posted at

はじめに

Laravelのアクセサ・ミューテタを使うと、データベースからデータを取得 / 保存する際に、毎回実行したいデータ加工の処理を定義することができる。

今回はこれらの使用方法を備忘録としてまとめておく。

アクセサ・ミューテタとは?

アクセサ

DBからデータを取得する時に、特定の処理を行う機能。

【使用例】

(1)DBからユーザーの名前を取得する際に、大文字小文字の変換を行う。

(2)DBからユーザーデータを取得する際に、既存カラムを使って作成した新しい属性値も含める。

ミューテタ

データベースへデータを保存する時に、特定の処理を行う機能。

【使用例】

データベースに郵便番号を保存する際に、ハイフンを取り除いて半角に変換した上で保存する。

これらアクセサとミューテタの使用方法を、Readoubleに記載の例を引用して説明する。

Laravel 8.x Eloquent:ミューテタ/キャスト

アクセサの使用方法

モデルにget◯◯Attributeという名前でメソッドを作成すると、Laravelが自動的にアクセサだと判断してくれる。

この際、メソッド名の◯◯の部分に加工したいカラム名をアッパーキャメルケースで指定する。

アクセサはDBからのデータ取得時にデータを加工するための機能だが、以下の2通りの使い方ができる。

① DBにあるカラム名と同じカラム名でデータを返す場合

② DBにあるカラムを使って、新しいカラム名でデータを返す(DBのテーブルに実際には存在しないカラムを、独自に作ることができるイメージ)

それぞれの使い方を説明する。

使用方法①:DBにあるカラム名と同じカラム名でデータを返す場合

以下は、DBのusersテーブルに実際に存在する first_name というカラムの値を加工する例。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザーの名前の取得
     *
     * @param  string  $value
     * @return string
     */
    public function getFirstNameAttribute($value)
    {
        return ucfirst($value);
    }
}

これにより、カラムの元の値がアクセサに $value として渡され、PHPのucfirst関数により最初の文字を大文字に変換した結果の値を返す。

よって例えば、 User::find(1); のようにデータを取得すると、DBのデータが「hanako」だった場合、レスポンスでは「Hanako」に変換されているということになる。

使用方法②:DBにあるカラムを使って、新しいカラム名でデータを返す場合

アクセサは既存のカラムを使って、新しい属性を作り出してレスポンスに含めることもできる。

以下は、DBのusersテーブルに既存の first_name と last_name というカラムを使用して、 full_name という新しい属性を作成して返す例。

full_name という属性を作るので、メソッド名は getFullNameAttribute() とする。

/**
 * ユーザーのフルネームの取得
 *
 * @return string
 */
public function getFullNameAttribute()
{
    return "{$this->first_name} {$this->last_name}";
}

例えば、 User::f``ind(1); のようにデータを取得すると、DBには full_name というカラムは存在しなくても、あたかもDBに full_name というカラムが存在するかのように、返り値には full_name という属性が含まれている。

以下のように記述することで、DBに存在するカラムと同じように full_name の値にアクセスすることができる。

$user = App\User::find(1);
$fullName = $user->full_name;

使用方法②の注意点

DBから取得したデータをJSON形式でフロント側にレスポンスとして返す、、というような場面もあるだろう。

モデルのデータを配列やJSONに変換する時に、使用方法②で作成したDBにはカラムが無い属性も含めたい場合は、アクセサの使用に加えてモデルの appends プロパティに属性を設定する必要がある。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * モデルの配列フォームに追加するアクセサ
     *
     * @var array
     */
    protected $appends = ['full_name'];
}

属性をappendsリストへ追加すると、配列やJSON形式のレスポンスにも含まれるようになる。

またappends プロパティに設定した属性は、モデルで設定されたvisibleおよびhiddenの設定も尊重する。

ミューテタの使用方法

ミューテタを使用すると、DBへのデータ保存時にデータを加工することができる。

モデルにset◯◯Attributeという名前でメソッドを作成すると、Laravelが自動的にミューテタだと判断してくれる。

この際、メソッド名の◯◯の部分に加工したいカラム名をアッパーキャメルケースで指定する。

以下は、usersテーブルの first_name というカラムへデータを保存する際に、PHPのstrtolowerメソッドを使用して、受け取った文字列を全て小文字に変換する例。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザーの名前を設定
     *
     * @param  string  $value
     * @return void
     */
    public function setFirstNameAttribute($value)
    {
        $this->attributes['first_name'] = strtolower($value);
    }
}

ミューテタは入力された値を $value として受け取る。

$this->attributes['first_name'] でEloquentモデルの first_name へアクセスできるので、ここに整形後の値を設定する。

さいごに

業務でアクセサが使った記述があったのだが、ルールに沿ったメソッド名で定義すればLaravelが自動的にアクセサとして扱ってくれるというものなので、アクセサを知らずにコードを読んでいると中々仕組みに気付けなかった。

だが知っていれば非常に便利なフレームワークの機能なので、今後はこの機能を自分の引き出しの一つとして、有効な場面で使えるように覚えておきたい。

参考記事

2
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
2
0