Mysql 强制转换属性用于外键查询,而不是本机类型
我们在mysql数据库中使用二进制UUID,并将它们转换为模型上的字符串。在Laravel5.7中,这对我们来说非常有效,但在6.x中,这并没有达到预期效果 我们可以使用二进制uuid创建记录和相关记录。但是,我们无法读取该关系,因为强制转换值与数据库中的内容不匹配,所以它显示为空 您可以看到正在使用二进制Mysql 强制转换属性用于外键查询,而不是本机类型,mysql,laravel,eloquent,uuid,laravel-6,Mysql,Laravel,Eloquent,Uuid,Laravel 6,我们在mysql数据库中使用二进制UUID,并将它们转换为模型上的字符串。在Laravel5.7中,这对我们来说非常有效,但在6.x中,这并没有达到预期效果 我们可以使用二进制uuid创建记录和相关记录。但是,我们无法读取该关系,因为强制转换值与数据库中的内容不匹配,所以它显示为空 您可以看到正在使用二进制id和外键user\u id创建post记录 [2019-11-27 05:39:57] local.INFO: insert into `posts` (`title`, `user_id`
id
和外键user\u id创建post
记录
[2019-11-27 05:39:57] local.INFO: insert into `posts` (`title`, `user_id`, `id`, `updated_at`, `created_at`) values (?, ?, ?, ?, ?)
[2019-11-27 05:39:57] local.INFO: array (
0 => 'Veniam error quod minima. Error laborum voluptatum sunt exercitationem dolor. Quis qui ipsa occaecati iste minus dolor omnis.',
1 => '=��K�WE3��wQ
��',
2 => '�7n��kLS�T$�L�',
3 => '2019-11-27 05:39:57',
4 => '2019-11-27 05:39:57',
但是如果您尝试查询关系,例如$user->posts
,则会使用user\u id
的强制转换值
[2019-11-27 05:39:57] local.INFO: select * from `posts` where `posts`.`user_id` = ? and `posts`.`user_id` is not null
[2019-11-27 05:39:57] local.INFO: array (
0 => '3d93a84b-fb57-4533-96ab-1c77510ab4e0',
)
因此没有发现任何记录
这是laravel中的一个bug吗?它应该使用select查询的本机类型而不是强制转换值,不是吗
模型上的方法基本上是:
铸造
protected function castAttribute($key, $value)
{
if (in_array($key, $this->uuidColumns()) && !empty($value)) {
return $this->resolveUuid()->fromBytes($value)->toString();
}
return parent::castAttribute($key, $value);
}
以及在创建模型时创建UUID的引导方法
public static function bootGeneratesUuid(): void
{
static::creating(function ($model) {
/* @var \Illuminate\Database\Eloquent\Model|static $model */
$uuid = $model->resolveUuid();
foreach ($model->uuidColumns() as $item) {
if (isset($model->attributes[$item]) && !is_null($model->attributes[$item])) {
/* @var \Ramsey\Uuid\Uuid $uuid */
$uuid = $uuid->fromString(strtolower($model->attributes[$item]));
}
$model->attributes[$item] = $model->hasCast($item, 'uuid') ? $uuid->getBytes() : $uuid->toString();
}
});
}
我在这里做了详细的复制