-
Notifications
You must be signed in to change notification settings - Fork 11.5k
Closed
Labels
Description
- Laravel Version: 7.15.0
- PHP Version: 7.3.7
- Database Driver & Version: 10.3.16-MariaDB
Description:
The problem is that value objects are not casted back when call Client::toJson()
.
So, for example we have next model:
App\Models\Client {#4028
id: 7,
name: "asdf@asdf.com",
email_verified_at: null,
}
Accessing name
property gives us Name
value object:
App\ValueObjects\Name^ {#4027
#name: "asdf@asdf.com"
}
When we call $client->toJson()
, we get empty object instead of primitive value:
{"id":7,"name":{},"email_verified_at":null}
Steps To Reproduce:
Client Eloquent Model:
class Client extends Authenticatable
{
use Notifiable;
protected $table = 'users';
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'name' => NameCast::class,
'password' => PasswordCast::class,
];
}
Name Cast:
class NameCast implements CastsAttributes
{
public function get($model, string $key, $value, $attributes)
{
return Name::create($value);
}
public function set($model, string $key, $setName, $attributes)
{
if (!$setName instanceof Name) {
throw new \InvalidArgumentException('Parameter $setName must be instance of ' . Name::class);
}
return [
$key => $setName->value()
];
}
}
Name Value Object:
class Name
{
public const MIN_LENGTH = 2;
protected $name;
private function __construct(string $name)
{
if (mb_strlen($name) < self::MIN_LENGTH) {
throw new \InvalidArgumentException('Name must has at least ' . self::MIN_LENGTH . ' characters');
}
$this->name = $name;
}
public static function create(string $name): Name
{
return new static($name);
}
public function value()
{
return $this->name;
}
}