Open maxrice opened 1 month ago
Hey @maxrice
Thanks for opening this issue. I did not know this feature of Eloquent, I have always used the $cast
property.
Since this is a correction that may impact the functioning of the library, I prefer to fix this bug in the next major release: 4.0.0. I hope to release the 4.x.x
in november.
As stated at the beginning of the issue, the easiest way is to go through the $casts
property.
Best,
@dimitriBouteille yeah it seems like it depends on the driver being used, based on https://github.com/laravel/framework/issues/11780, anyhow. So it might be worth some additional investigation when you start working on the next major release, but not a big deal to use the $casts
property either. thanks!
Hi @maxrice
I’m looking to fix this problem. However, I don’t see any reference in Laravel or Eloquent that automatically cast an attribute according to the type of column.
I tried to install a Laravel project to see if there is a difference, and laravel also uses the manual cast system.
When installing Laravel, the User
class is automatically created and uses the casts
function :
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}
When I disable the cast of the email_verified_at
property, it is a string type that is returned :
/** @var \App\Models\User $user */
$user = \App\Models\User::find(1);
dd($user, $user->email_verified_at, $user->getAttribute('email_verified_at'));
Do you have a link to documentation that talks about this automatic cast?
@dimitriBouteille It doesn't seem to be mentioned explicitly in the docs, though I did find a few mentions in blog posts about how this is done "automatically". From re-reading https://github.com/laravel/framework/issues/11780, I think this happens in the database driver itself, not Laravel, so it probably can't be "fixed" in WP ORM; could consider adding a note to the docs about using the $casts
property?
Describe the bug
AFAIK, Eloquent will cast attributes to the column type as defined in the table. When adding a custom model with say, an integer column, the attribute type when accessing it like
$instance->attribute
will always be a string instead of integer.Steps to reproduce the issue
Create a custom model:
and a matching table:
Insert a record into the table:
Then, load the model and dump the integer column:
And you'll get:
Interestingly, if you add the column to the
$casts
property, like:then you get the expected behavior:
IMO that's an acceptable workaround if there's no way to have Eloquent automatically cast the column values, due to a conflict with
$wpdb
or something.Your setup