mr_reboot's avatar

Eloquent model attributes are always string? Even with casts?

I'm sure i'm doing something wrong, but any value I return using eloquent is a string. Even if I specifically tell the model to cast to something else. I am using MSSQL 2016 for the database.

For example I have a ProjectsCtcWorksheet model:

$worksheet = ProjectsCtcWorksheet::with('items')->where('id', $id)->firstOrFail();

There is an attribute there 'original_contract' that is stored as a decimal in MSSQL. Yet eloquent always returns string. I even went into the model and defined casts:

protected function casts(): array { return [ 'original_contract' => 'decimal:2', ]; }

Yet this still returns a string:

dd(gettype($worksheet->original_contract));

This is from my migration just to prove the column is a decimal:

$table->decimal('original_contract', $precision = $precision_default, $scale = $scale_default);

What am I doing wrong?

Edit I also tried it using the $casts property on the model and same issue:

        'original_contract'        => 'decimal:2',
    ];
0 likes
3 replies
LaryAI's avatar
Level 58

It looks like you're encountering an issue with the type casting in your Eloquent model. The problem might be due to the way you defined the casts method. In Laravel, the casts property should be defined as a public property, not as a method.

Here's how you can properly define the casts property in your model:

class ProjectsCtcWorksheet extends Model
{
    protected $casts = [
        'original_contract' => 'decimal:2',
    ];
}

Make sure that you are not defining casts as a method but as a property. This should ensure that the original_contract attribute is cast to a decimal with 2 decimal places.

Here is a complete example:

use Illuminate\Database\Eloquent\Model;

class ProjectsCtcWorksheet extends Model
{
    protected $casts = [
        'original_contract' => 'decimal:2',
    ];
}

After making this change, when you retrieve the original_contract attribute, it should be cast to a decimal as expected:

$worksheet = ProjectsCtcWorksheet::with('items')->where('id', $id)->firstOrFail();
dd(gettype($worksheet->original_contract)); // This should now output "double" or "float"

If you still encounter issues, ensure that your database column is indeed a decimal type and that there are no other parts of your code that might be interfering with the casting. Additionally, you can try clearing your configuration cache:

php artisan config:cache
php artisan config:clear

This should resolve the issue and ensure that your attribute is properly cast to a decimal.

mr_reboot's avatar

Hmmm...here is something interesting. If I change 'decimal:2' to 'float' suddenly the type becomes 'double'.

Any idea why decimal isn't working?

Please or to participate in this conversation.