PeteBatin's avatar

Eloquent model ignoring casts

Hi all,

I've two Laravel sites, one public facing and one internal (intranet). They share a database for one particular service aspect, one-time secret sharing. The intranet creates data entries that are later retrieved on public facing site (this will later be replaced with an API).

The models I have on both sites are almost identical (difference being on the public site there are no fillable columns).

The casts are exactly identical.

On the Intranet site the casts work as expected and when I perform a dump on the retrieved model I see this.

#casts: array:2 [▼
    "secret" => "App\Casts\SecretEncrypt"
    "passphrase" => "App\Casts\SecretEncrypt"
  ]

However on the public site, it's completely ignoring the casts.

#casts: []

This is my model

<?php

namespace App\Models;

use Illuminate\Support\Str;
use App\Casts\SecretEncrypt;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Secrets extends Model
{
    use HasFactory;

    protected $keyType = 'string';

    protected function casts(): array
    {
        return [
            'secret' => SecretEncrypt::class,
            'passphrase' => SecretEncrypt::class,
        ];
    }
}

And this is my cast

There is no attempt by Eloquent to perform the get() method, the data is outputted exactly as stored in the DB.

Any ideas?

I've ran artisan cache:clear and config:cache but it's made no difference, also ran composer dump-autoload in case it was a autoload issue and stopped/started artisan serve

0 likes
2 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

The issue is likely due to the way you are defining your casts in the model. In Laravel, the casts property should be a protected property, not a method. The protected function casts(): array syntax is only supported in Laravel 9.21 and above (see Laravel release notes). If your public site is running an older Laravel version, it will ignore the method and look for the property instead.

How to fix:

Replace your casts() method with a protected $casts property in your model:

<?php

namespace App\Models;

use Illuminate\Support\Str;
use App\Casts\SecretEncrypt;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Secrets extends Model
{
    use HasFactory;

    protected $keyType = 'string';

    protected $casts = [
        'secret' => SecretEncrypt::class,
        'passphrase' => SecretEncrypt::class,
    ];
}

Why does this work?

  • Laravel versions prior to 9.21 only support the $casts property.
  • If you use the casts() method on an older version, it will be ignored, resulting in an empty #casts array.

Next steps:

  1. Update your model as shown above.
  2. Clear your config and cache again:
    php artisan config:clear
    php artisan cache:clear
    
  3. Test retrieving your model again.

If you want to use the casts() method, make sure your Laravel version is 9.21 or above.


Summary:
On your public site, use the $casts property instead of the casts() method unless you're sure you're running Laravel 9.21+. This should resolve the issue of Eloquent ignoring your casts.

1 like

Please or to participate in this conversation.