0

Relationship constraints — with(['posts' => fn($q) => $q->where(...)])

Intermediate5 min read·lv-12-012
sql

Concept

Model serialization is the process of converting an Eloquent model to arrays and JSON for API responses, session storage, and event broadcasting.

toArray(): Converts model to a PHP array. Includes all visible attributes, casts, and appended accessors. Loaded relationships are also converted to arrays.

toJson($options = 0): Converts to JSON string. json_encode($model) is equivalent — models implement JsonSerializable. JSON_PRETTY_PRINT flag for human-readable output.

Controlling visibility:

  • $hidden: Exclude from toArray(). $model->makeVisible('password') temporarily removes from hidden.
  • $visible: Allowlist — only include these attributes. $model->makeHidden('name') temporarily hides.
  • These protect sensitive fields in API responses. Always keep password, remember_token, api_key in $hidden.

$appends: Include accessors (computed properties) in serialization output.

Relationships in serialization: Relationships are only included in toArray() if they've been loaded (either via eager loading or property access). This means serialization output can vary depending on what relationships are loaded — be explicit.

API Resources (lv-24): The recommended approach for API serialization. Resources transform models with explicit control over output format, versioning, and conditional fields. Prefer Resources over raw toArray() for APIs.

load() before serialization: Ensure relationships you need are loaded: $user->load('roles', 'profile')->toArray().

Code Example

php
<?php
$user = User::with('posts', 'profile')->find(1);

// toArray — includes loaded relationships
$array = $user->toArray();
// [
//   'id' => 1,
//   'name' => 'Alice',
//   'email' => 'alice@example.com',
//   'full_name' => 'Alice Smith',  // from $appends
//   'posts' => [...],              // because eager loaded
//   'profile' => {...},            // because eager loaded
//   // 'password' NOT included — in $hidden
// ]

// toJson
$json = $user->toJson();
$json = $user->toJson(JSON_PRETTY_PRINT);

// json_encode works because Model implements JsonSerializable
$json = json_encode($user); // equivalent to toJson()

// Temporarily expose hidden field
$array = $user->makeVisible('two_factor_secret')->toArray();

// Temporarily hide a field
$array = $user->makeHidden(['email', 'phone'])->toArray();

// Only serialize specific attributes — makeHidden doesn't affect collections
// Use API Resources for granular control in production

// Collection serialization
$users = User::all();
$array = $users->toArray();  // array of model arrays
$json  = $users->toJson();   // JSON array

// Only loaded relationships appear in output
$user = User::find(1);      // no eager load
$user->toArray();            // NO 'posts' key
$user->load('posts');
$user->toArray();            // 'posts' key now present

// Be explicit in API endpoints
return response()->json(
    $user->load('roles', 'profile')->makeHidden('remember_token')
);