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
Help us understand the problem. What is going on with this article?

Transformerという概念を取り入れてみよう【Laravel】

More than 1 year has passed since last update.

オープンソース見ていていいなと思ったので紹介します。
一言で言えばDB上のデータを整形するクラス。
機能というよりは概念なのでそんな難しいことじゃないです。

男の子はTransformerって響き好きですよね?!
あの、変形するやつです(車が変形するってことしか知りませんが...)
正直Transformerって言いたいってそれだけの勢いで執筆してます

どういう時につかう?

名前:{{ $student->name }}

性別:{{ config(“trans.gender.{$student->gender}”) }}

生年月日:{{ $student->birthday_y }}年{{ $student->birthday_m }}月{{ $student->birthday_d }}

こんな感じのbladeテンプレート記述した人は多いと思います。

一回書くだけなら、何も問題ないのですが、色々な場所で性別描画したいとか、
誕生日描画したいとかなってくると結構うざいですよね😅
そんな時にデータベースから引っ張ってきてすぐ描画できる形に変換するのも手。
(特に、データ弄るより単純に描画させたいケースの方が多いと思います。コード値で保存したり誕生日を別々で保管しておくと編集フォームでの利用に楽だったりもするのですが)

そこで導入したいのがTransformerという概念。
これから説明するのは簡単にいうとデータの整形用クラスなのですが、
こんな感じにデータ取り出してからの整形方法をまとめて定義しておくと、
ヘルパあるのに知らなかったぁ😰とか、あっちやこっちで整形方法違うくて
混乱しちゃうぅ😫とかならなくても済みます。
探せばライブラリとかもあるようですが、難しいことでもないので自作しましょう!
以下が私が参考にした記述。

Transformerを書いてみる

//Transformer本体ですよ
class StudentTransformer
{
    Public function __invoke(Student $student) //invokeがミソ
    {
        $data = [
        ‘name’ = $student->name,

        ‘gender’ = config(“trans.gender.{$student->gender}”),

        ‘birthday’ = $student->birthday_y . ‘年’ . $student->birthday_m . ‘月’ . $student->birthday_d . ‘日’,
        ];

        return $data;
    }
}
//Controllerですよ
Public function index(Student $student)
{
    $studentArray = (new StudentTransformer)($student); //ちょっと特殊な書き方

    return text(‘student.index’, [‘student’ => $studentArray]); 
}
//viewですよ(タグつけてサンプルかくのだるいのでテキストw)
名前:{{ $student[‘name’] }}

性別:{{ $student[‘gender’] }}

生年月日:{{ $student[‘birthday’] }}

nullで定義づけもされるのでundefinedエラー吐くこともないはず。
一度定義さえしてしまえば、コード値から文字列のデータを引き出す際に
一々configやtransディレクトリとにらめっこしたりする必要もないので大分楽になると思います。
あと場合によっては文字列整形が必要なデータもあったりするので、
そういった整形方法を統一化することも容易となります.
何より一個のファイルとしてクラスまんま他に置いておけるのはわかりやすい、
まぁぶっちゃけTraitなどでも良いかもですが。。。

一対多リレーションの時

一対多リレーションを組みたくなっちゃった時は少しコツがいります。
foreachとかでも良いんですけど。もっとオシャレにスタイリッシュに
書くなら私はこうします。

public function detail(Student $student)
{
    $studentArray = (new StudentTransformer)($student);

    $hobbyArray = $student->hobbies()
        ->get()
        ->transform(function($hobby)
            return (new HobbyTransformer)($hobby);
         });

    return text(‘student.detail’, 
                [
                 ‘student’ => $studentArray;
                 ‘hobbies’ => $hobbyArray;
                 ]);
}

まとめ

DBのデータを引き出しして実際にフロントで扱えるようにするフローを分かりやすく、
統一化出来るという意味で気に入っております😆
LaravelのEloquentコレクションそのままフロントに引き渡すのもそれで潤沢な
メリットはあるのですが、vueとかreactとかを導入していてDBから受け取った
配列の扱いをjsにぶん投げたい時はPHPのオブジェクトで引き渡せないので
整形してArrayに直す際にTransformerは重要な考え方になるかと思います。

あくまで機能ではなく概念なのでライブラリを使ってみたりtraitで記述してみたり、はたまた
モデルにメソッドを追加してみたりなどプロジェクトと趣向に応じて是非とも柔軟に取り入れてみてください。

fumifumitaro
のんびりカタカタしている人です
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