Search code examples
phplaraveltinker

Laravel: Why is Eloquent displaying hidden fields?


Simply prefixes a # to the field name

I am using Laravel Breeze, which by default sets the password and remember_token fields to hidden.

class User extends Authenticatable
{
    use HasFactory, Notifiable;

    protected $fillable = [
        'username',
        'email',
        'password',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

However if I fetch a User instance running User::inRandomerOrder()->first() inside Tinker I am still able to see these supposed hidden fields.

App\Models\User {#4440
 id: 14,
 username: "verdie10",
 email: "[email protected]",
 email_verified_at: "2021-08-31 11:19:47",
 #password: "$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi",
 #remember_token: "F87k6RPxgi",
 created_at: "2021-08-31 11:19:47",
 updated_at: "2021-08-31 11:19:47",
},

Solution

  • That's because these fields are only hidden when you convert your model to array or JSON.

    From the documentation:

    Sometimes you may wish to limit the attributes, such as passwords, that are included in your model's array or JSON representation.

    The whole documentation about this topic is available here: https://laravel.com/docs/8.x/eloquent-serialization#hiding-attributes-from-json

    The goal is to remove them from your API responses.

    However, you might still use them when you are working with your models in controllers, services... that's why you see them.

    You can check it works by doing:

    $user = User::first();
    $user->toArray(); // hidden attributes not included
    $user->toJson(); // hidden attributes not included