はじめに

Laravelを使用してAPIを構築する際、モデルやリレーションを配列またはJSONに変換する必要がよくあります。Eloquentには、これらの変換を行うための便利なメソッドが含まれており、モデルのシリアライズされた表現に含まれる属性を制御することもできます。

より堅牢なEloquentモデルとコレクションのJSONシリアル化の方法については、Eloquent APIリソースのドキュメントを確認してください。

モデルとコレクションのシリアル化

配列へのシリアル化

モデルとその読み込まれたリレーションを配列に変換するには、toArrayメソッドを使用する必要があります。このメソッドは再帰的であるため、すべての属性とすべてのリレーション(リレーションのリレーションを含む)が配列に変換されます:

  1. use App\Models\User;
  2. $user = User::with('roles')->first();
  3. return $user->toArray();
  1. ``````php
  2. $user = User::first();
  3. return $user->attributesToArray();
  4. `

モデルのコレクション全体を配列に変換するには、コレクションインスタンスでtoArrayメソッドを呼び出します:

  1. $users = User::all();
  2. return $users->toArray();

JSONへのシリアル化

モデルをJSONに変換するには、toJsonメソッドを使用する必要があります。toArrayと同様に、toJsonメソッドは再帰的であるため、すべての属性とリレーションがJSONに変換されます。また、PHPによってサポートされている任意のJSONエンコーディングオプションを指定することもできます:

  1. use App\Models\User;
  2. $user = User::find(1);
  3. return $user->toJson();
  4. return $user->toJson(JSON_PRETTY_PRINT);

また、モデルまたはコレクションを文字列にキャストすることもでき、これによりモデルまたはコレクションのtoJsonメソッドが自動的に呼び出されます:

  1. return (string) User::find(1);

モデルとコレクションは文字列にキャストされるとJSONに変換されるため、アプリケーションのルートやコントローラーからEloquentオブジェクトを直接返すことができます。Laravelは、ルートやコントローラーから返されるときにEloquentモデルとコレクションを自動的にJSONにシリアライズします:

  1. Route::get('/users', function () {
  2. return User::all();
  3. });

リレーションシップ

EloquentモデルがJSONに変換されると、その読み込まれたリレーションシップは自動的にJSONオブジェクトの属性として含まれます。また、Eloquentのリレーションメソッドは「キャメルケース」メソッド名を使用して定義されていますが、リレーションシップのJSON属性は「スネークケース」になります。

JSONから属性を隠す

時には、パスワードなどの属性をモデルの配列またはJSON表現に含めないように制限したい場合があります。そのためには、モデルに$hiddenプロパティを追加します。$hiddenプロパティの配列にリストされている属性は、モデルのシリアライズされた表現に含まれません:

  1. <?php
  2. namespace App\Models;
  3. use Illuminate\Database\Eloquent\Model;
  4. class User extends Model
  5. {
  6. /**
  7. * The attributes that should be hidden for arrays.
  8. *
  9. * @var array
  10. */
  11. protected $hidden = ['password'];
  12. }

リレーションシップを隠すには、リレーションシップのメソッド名をEloquentモデルの$hiddenプロパティに追加します。

また、visibleプロパティを使用して、モデルの配列とJSON表現に含めるべき属性の「許可リスト」を定義することもできます。$visible配列に存在しないすべての属性は、モデルが配列またはJSONに変換されるときに隠されます:

  1. <?php
  2. namespace App\Models;
  3. use Illuminate\Database\Eloquent\Model;
  4. class User extends Model
  5. {
  6. /**
  7. * The attributes that should be visible in arrays.
  8. *
  9. * @var array
  10. */
  11. protected $visible = ['first_name', 'last_name'];
  12. }

属性の可視性を一時的に変更する

特定のモデルインスタンスで通常隠されている属性を表示したい場合は、makeVisibleメソッドを使用できます。makeVisibleメソッドはモデルインスタンスを返します:

  1. return $user->makeVisible('attribute')->toArray();

同様に、通常表示されている属性を隠したい場合は、makeHiddenメソッドを使用できます。

  1. return $user->makeHidden('attribute')->toArray();

すべての可視または隠された属性を一時的にオーバーライドしたい場合は、それぞれsetVisibleおよびsetHiddenメソッドを使用できます:

  1. return $user->setVisible(['id', 'name'])->toArray();
  2. return $user->setHidden(['email', 'password', 'remember_token'])->toArray();

JSONに値を追加する

モデルを配列またはJSONに変換する際に、データベースに対応するカラムがない属性を追加したい場合があります。そのためには、まずその値のアクセサを定義します:

  1. <?php
  2. namespace App\Models;
  3. use Illuminate\Database\Eloquent\Casts\Attribute;
  4. use Illuminate\Database\Eloquent\Model;
  5. class User extends Model
  6. {
  7. /**
  8. * Determine if the user is an administrator.
  9. */
  10. protected function isAdmin(): Attribute
  11. {
  12. return new Attribute(
  13. get: fn () => 'yes',
  14. );
  15. }
  16. }

アクセサを常にモデルの配列およびJSON表現に追加したい場合は、モデルのappendsプロパティに属性名を追加します。属性名は通常「スネークケース」のシリアライズされた表現を使用して参照されますが、アクセサのPHPメソッドは「キャメルケース」で定義されています:

  1. <?php
  2. namespace App\Models;
  3. use Illuminate\Database\Eloquent\Model;
  4. class User extends Model
  5. {
  6. /**
  7. * The accessors to append to the model's array form.
  8. *
  9. * @var array
  10. */
  11. protected $appends = ['is_admin'];
  12. }

属性がappendsリストに追加されると、それはモデルの配列とJSON表現の両方に含まれます。appends配列の属性も、モデルに設定されたvisibleおよびhiddenの設定を尊重します。

実行時に追加する

実行時に、モデルインスタンスに追加の属性を追加するよう指示するには、appendメソッドを使用します。また、setAppendsメソッドを使用して、特定のモデルインスタンスの追加されたプロパティの配列全体をオーバーライドすることもできます:

  1. return $user->append('is_admin')->toArray();
  2. return $user->setAppends(['is_admin'])->toArray();

日付のシリアル化

デフォルトの日付形式をカスタマイズする

  1. ``````php
  2. /**
  3. * Prepare a date for array / JSON serialization.
  4. */
  5. protected function serializeDate(DateTimeInterface $date): string
  6. {
  7. return $date->format('Y-m-d');
  8. }
  9. `

属性ごとの日付形式をカスタマイズする

個々のEloquent日付属性のシリアル化形式をカスタマイズするには、モデルのキャスト宣言で日付形式を指定します:

php protected function casts(): array { return [ 'birthday' => 'date:Y-m-d', 'joined_at' => 'datetime:Y-m-d H:00', ]; }@