はじめに
Laravelを使用してAPIを構築する際、モデルやリレーションを配列またはJSONに変換する必要がよくあります。Eloquentには、これらの変換を行うための便利なメソッドが含まれており、モデルのシリアライズされた表現に含まれる属性を制御することもできます。
より堅牢なEloquentモデルとコレクションのJSONシリアル化の方法については、Eloquent APIリソースのドキュメントを確認してください。
モデルとコレクションのシリアル化
配列へのシリアル化
モデルとその読み込まれたリレーションを配列に変換するには、toArray
メソッドを使用する必要があります。このメソッドは再帰的であるため、すべての属性とすべてのリレーション(リレーションのリレーションを含む)が配列に変換されます:
use App\Models\User;
$user = User::with('roles')->first();
return $user->toArray();
``````php
$user = User::first();
return $user->attributesToArray();
`
モデルのコレクション全体を配列に変換するには、コレクションインスタンスでtoArray
メソッドを呼び出します:
$users = User::all();
return $users->toArray();
JSONへのシリアル化
モデルをJSONに変換するには、toJson
メソッドを使用する必要があります。toArray
と同様に、toJson
メソッドは再帰的であるため、すべての属性とリレーションがJSONに変換されます。また、PHPによってサポートされている任意のJSONエンコーディングオプションを指定することもできます:
use App\Models\User;
$user = User::find(1);
return $user->toJson();
return $user->toJson(JSON_PRETTY_PRINT);
また、モデルまたはコレクションを文字列にキャストすることもでき、これによりモデルまたはコレクションのtoJson
メソッドが自動的に呼び出されます:
return (string) User::find(1);
モデルとコレクションは文字列にキャストされるとJSONに変換されるため、アプリケーションのルートやコントローラーからEloquentオブジェクトを直接返すことができます。Laravelは、ルートやコントローラーから返されるときにEloquentモデルとコレクションを自動的にJSONにシリアライズします:
Route::get('/users', function () {
return User::all();
});
リレーションシップ
EloquentモデルがJSONに変換されると、その読み込まれたリレーションシップは自動的にJSONオブジェクトの属性として含まれます。また、Eloquentのリレーションメソッドは「キャメルケース」メソッド名を使用して定義されていますが、リレーションシップのJSON属性は「スネークケース」になります。
JSONから属性を隠す
時には、パスワードなどの属性をモデルの配列またはJSON表現に含めないように制限したい場合があります。そのためには、モデルに$hidden
プロパティを追加します。$hidden
プロパティの配列にリストされている属性は、モデルのシリアライズされた表現に含まれません:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = ['password'];
}
リレーションシップを隠すには、リレーションシップのメソッド名をEloquentモデルの$hidden
プロパティに追加します。
また、visible
プロパティを使用して、モデルの配列とJSON表現に含めるべき属性の「許可リスト」を定義することもできます。$visible
配列に存在しないすべての属性は、モデルが配列またはJSONに変換されるときに隠されます:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that should be visible in arrays.
*
* @var array
*/
protected $visible = ['first_name', 'last_name'];
}
属性の可視性を一時的に変更する
特定のモデルインスタンスで通常隠されている属性を表示したい場合は、makeVisible
メソッドを使用できます。makeVisible
メソッドはモデルインスタンスを返します:
return $user->makeVisible('attribute')->toArray();
同様に、通常表示されている属性を隠したい場合は、makeHidden
メソッドを使用できます。
return $user->makeHidden('attribute')->toArray();
すべての可視または隠された属性を一時的にオーバーライドしたい場合は、それぞれsetVisible
およびsetHidden
メソッドを使用できます:
return $user->setVisible(['id', 'name'])->toArray();
return $user->setHidden(['email', 'password', 'remember_token'])->toArray();
JSONに値を追加する
モデルを配列またはJSONに変換する際に、データベースに対応するカラムがない属性を追加したい場合があります。そのためには、まずその値のアクセサを定義します:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Determine if the user is an administrator.
*/
protected function isAdmin(): Attribute
{
return new Attribute(
get: fn () => 'yes',
);
}
}
アクセサを常にモデルの配列およびJSON表現に追加したい場合は、モデルのappends
プロパティに属性名を追加します。属性名は通常「スネークケース」のシリアライズされた表現を使用して参照されますが、アクセサのPHPメソッドは「キャメルケース」で定義されています:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The accessors to append to the model's array form.
*
* @var array
*/
protected $appends = ['is_admin'];
}
属性がappends
リストに追加されると、それはモデルの配列とJSON表現の両方に含まれます。appends
配列の属性も、モデルに設定されたvisible
およびhidden
の設定を尊重します。
実行時に追加する
実行時に、モデルインスタンスに追加の属性を追加するよう指示するには、append
メソッドを使用します。また、setAppends
メソッドを使用して、特定のモデルインスタンスの追加されたプロパティの配列全体をオーバーライドすることもできます:
return $user->append('is_admin')->toArray();
return $user->setAppends(['is_admin'])->toArray();
日付のシリアル化
デフォルトの日付形式をカスタマイズする
``````php
/**
* Prepare a date for array / JSON serialization.
*/
protected function serializeDate(DateTimeInterface $date): string
{
return $date->format('Y-m-d');
}
`
属性ごとの日付形式をカスタマイズする
個々のEloquent日付属性のシリアル化形式をカスタマイズするには、モデルのキャスト宣言で日付形式を指定します:
php
protected function casts(): array
{
return [
'birthday' => 'date:Y-m-d',
'joined_at' => 'datetime:Y-m-d H:00',
];
}
@