Eloquentとは
Laravel Eloquentは、PHP構文を使用してデータベースとやりとりすることができるORM(Object-Relational Mapping)です。データベースとの作業に対してシンプルなAPIを提供し、開発者がレコードを簡単に作成、読み取り、更新、削除できるようにします。Eloquentは、テーブル間の関係を定義することも簡単にできるため、複雑なアプリケーションを構築するための強力なツールとなります。
Laravel Eloquentには、データベースとのやりとりに必要な機能が豊富にあります。たとえば、モデルを使用してデータベースのテーブルを表現し、モデルのプロパティにテーブルの列をマップすることができます。また、Eloquentは、テーブル間の一対一、一対多、多対多の関係を簡単に定義できるため、複雑なデータモデルを構築するのに役立ちます。
さらに、Eloquentは、クエリを簡単にビルドすることができます。クエリビルダを使用して、データベースからデータを取得する方法を細かく制御できます。クエリビルダは、SQLの知識がなくても簡単に使用できるため、開発者にとって非常に便利です。
総じて、Laravel Eloquentは、データベースとのやりとりを簡単にするための強力なツールです。開発者が複雑なアプリケーションを構築するための時間と労力を節約することができます。
今回は、意外と知らない便利な使い方を説明します。
toArray(),toJson()を使う
toArray()
とtoJson()
はLaravelのEloquent ORMで提供される2つのメソッドです。
toArray()
は、モデルとその関連を配列に変換するために使用されます。これはJSON APIで作業する場合や、ビューにデータを渡す場合に役立ちます。
toJson()
は、モデルとその関連をJSON文字列に変換するために使用されます。これもJSON APIで作業する場合に役立ちます。
両方のメソッドは、Eloquentモデルを簡単に異なる形式に変換して、アプリケーションのさまざまな部分で使用するための方法を提供します。
ですが、ほかの人のコードを見ると、意外と使っているひとが少ない印象です。get()でcollectionにしてforループやmapメソッドで配列に変換していることが多いです。
根本的に違う形でレスポンスを返さないといけない場合は仕方がないですが、特に細かく決まっていない場合はtoArray()などで一括変換してしまうのが便利ですね。
ですが、レスポンスに返したくないカラムや加工したいカラムがある場合はどうしたらいいでしょうか?
属性を隠す
たとえば、パスワードやハッシュなどのレスポンスから隠したいレスポンスはどうするべきでしょうか?
もちろんselectメソッドを使ってもよいですが、毎回指定するのは面倒です。
それには、モデルに$hiddenプロパティーを追加して、配列に隠したい属性を指定します。
protected $hidden = ['password'];
隠したいもののほうが多い場合もあるかと思います。その場合は、$visible で許可リストタイプの指定も可能です。
protected $visible = ['first_name', 'last_name'];
また、一時的に変更したい場合は、それぞれ以下のようにすることで、動的に上書きできます。
return $user->makeVisible('attribute')->toArray();
return $user->makeHidden('attribute')->toArray();
属性を追加する
カラムを加工したい場合はどうしたらいいでしょうか?
たとえば、first_name と last_name
をつなげて出したいといった場合です。
その場合には、getXXXXAttribute()と$appends 属性を使います。
$appends = ['full_name']; public function getIsFullNameAttribute() { return $this->first_name.' '.$this->last_name; }
なお、appends 属性でカラムが追加されたことを教えてあげないと、toArray()などでシリアライズしたときに出てこない点に注意してください。
また、メソッド名も注意で、カラム名の部分はアッパーキャメル(先頭が大文字キャメルケース)、appendsの指定はテーブルのカラムと同じくスネークケースになります。
これで、いちいちループして配列に追加する処理を書かずに済みます。
もちろん、リレーション先のカラムも参照することができますので、それらを使ったカラムの追加も可能です。例えば、リレーション先のレコード数などがよくある例です。
ちなみに、appends属性も動的に変更することが可能で、以下のような書式です
return $user->append('full_name')->toArray();
return $user->setAppends(['full_name'])->toArray();
1個だけ追加ならappendメソッド、setAppends()メソッドで、全体を上書きできます。
属性のキャスト
属性のキャストもすることができます。
protected $casts = [
'is_admin' => 'boolean',
];
利用例としては、日付のフォーマットなどを統一したい場合に使うと便利です。
他にもキャストできるものはたくさんありますが、リンクの紹介にとどめます
https://readouble.com/laravel/8.x/ja/eloquent-mutators.html#attribute-casting
リレーション先のカラム出力制御
リレーション先のカラムの出力を制御するにはどうしたらいいでしょうか?
リレーションはwith()メソッドで追加できますが、ここでカラムの制御が可能です。
$model->with('model_names', function($query){
$query->select(['カラム名']);
});
makeHidden
を使ってもいいかもしれません。
まとめ
いかがだったでしょうか?
複雑なビジネスロジックの場合は難しい場合もありますが、単にレコードの内容を返すだけであれば、いちいち配列に展開して加工するよりも、EloquentやQueryでできるだけ加工して出力することで、工数や計算量などを大幅に節約できます。