LoginSignup
15
2

【Laravel】アクセサとミューテタについて

Last updated at Posted at 2023-03-28

はじめに

業務で実装のレビューを頂く中で、アクセサとミューテタについて学んだので備忘録として残したいと思います。

レビューを頂く前の実装

test.blade.php
<div>{{ $data->opened_at->format('Y年m月d日') }}</div>

取得したデータを求める形にフォーマットして画面に表示したい場面で、上記のように実装をしていました。
このような場面で使えるのが、データベースからデータを取得する際に、データ加工ができるアクセサです。

アクセサとは

上記でも記載しましたが、アクセサはデータベースからデータを取得する際に走る処理です。
日本語ドキュメントには下記のように記されています。

アクセサは、Eloquentの属性値にアクセスが合った時に、その値を変換するものです。

アクセサの使い方

アクセサはモデルに定義をし、メソッド名はデータベースカラムのキャメルケースにする必要があります。
全てのメソッドの戻り値はAttributeインスタンスとなります。
この戻り値のAttributeクラスのコンストラクタにget引数で処理を設定することで、対象のデータベースカラムにアクセスし処理を実行します。

例えば日時を表すopened_atというカラムを年月日の形にフォーマットするアクセサを定義したい場合は、以下のようになります。

Models/Test.php
protected function openedAt(): Attribute
{
    return Attribute::make(
        get: fn ($value) => $value->format('Y年m月d日')
    );
}

opened_atの値が入っている$valueを使って、フォーマット処理を実装します。
また、アクセサの値を取得する際は、取得したいデータ(上記の例で言うとopened_at)を呼び出すだけです。
以下のように呼び出すと、アクセサでフォーマットされて年月日の形で表示されます。

test.blade.php
<div>{{ $data->opened_at }}</div>

ミューテタとは

次にミューテタとはアクセサの逆で、データをデータベースに保存する際に走る処理です。
日本語ドキュメントには下記のように記されています。

ミューテタはEloquentの属性値を設定するときに、その値を変換するものです。

ミューテタの使い方

ミューテタもアクセサと同様に、モデルに定義をし、メソッド名はデータベースカラムのキャメルケースにする必要があります。
ミューテタはset引数を指定して、対象のデータベースカラムに設定したい値の処理を実装します。

例えばclosed_atというカラムに、同じモデルのclosed_code1の時だけ値を設定したい場合、以下のようになります。

Models/Test.php
protected function closedAt(): Attribute
{
    return Attribute::make(
        set: fn ($value, $attributes) => $attributes['closed_code'] == 1 ? $value : null
    );
}

$attributesにはモデルの現在の全ての属性を配列で持っているため、closed_atに値を設定する際に他のカラムデータも使うことができます。
またミューテタを使うにはアクセサと同様に、設定したいデータに値を設定するだけで自動的に呼び出されます。

TestController.php
$test = Test::find(1);
$test->closedCode = 0;
$test->closedAt = now(); // closedCodeが0なので、ミューテタによってnullが登録される

まとめ

アクセサとミューテタは、使うことでソースコードの記述が減りとても便利だと思います!
きちんと使いこなして、より簡潔に実装できるようにしていきたいです!

参考

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