Laravel Eloquent 多对多不保存密钥
Laravel Eloquent many-to-many not saving key
我试图在 Laravel 8 中建立一个简单的多对多关系,但我 运行 遇到了一个奇怪的问题。我正在建立相当标准的 User/Roles 关系,但有一个区别:我在这两个 table 上的主键是 UUID 而不是整数。
没有任何错误,但是当我将角色附加到具有 $user->roles()->attach($userRole);
的用户时,保存在 role_user
链接 table 中的数据丢失了 user_id
, role_id
被正确插入。我最初遇到 role_id
也没有保存的问题,但我发现这是在模型上指定 protected $keyType = 'string';
。
我无法解决的是,这是我使用 UUID 造成的,还是我做了其他根本错误的事情。
用户模型
class User extends Authenticatable
{
use HasFactory, Notifiable;
protected $primaryKey = 'id';
protected $keyType = 'string';
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
protected static function boot()
{
parent::boot();
self::creating(function ($model) {
$model->id = (string)Str::uuid();
});
}
public function roles()
{
return $this->belongsToMany('App\Models\Role')
->using('App\Models\RoleUser');
}
}
角色用户模型
class RoleUser extends Pivot
{
use HasFactory;
protected $primaryKey = 'id';
protected $keyType = 'string';
protected static function boot()
{
parent::boot();
self::creating(function ($model) {
$model->id = (string)Str::uuid();
});
}
}
我在数据库中得到的结果如下。
用户/角色分配代码
$adminRole = Role::where('name', 'admin')->first();
$userRole = Role::where('name', 'user')->first();
$admin = User::create(['name' => 'Admin User', 'email' => 'admin@myapp.com', 'password' => Hash::make('adminpass')]);
$admin->save();
$user = User::create(['name' => 'User User', 'email' => 'user@myapp.com', 'password' => Hash::make('userpass')]);
$user->save();
$admin->roles()->attach($adminRole);
$user->roles()->attach($userRole);
$user->save();
$admin->save();
我真的迷路了,可能是因为我是 Laravel 的新手。
因此,如果其他人遇到上述问题,我找到的解决方案是:
在迁移中构建 table 时,确保将 uuid 设置为主! $table->uuid('id')->primary();
所有模型都应该设置如下:
protected $primaryKey = 'id';
protected $keyType = 'string';
public $incrementing = false;
以上组合似乎解决了我的问题。它似乎正在构建用户模型但没有为其分配 UUID(尽管它已保存在数据库中)。如果我只是使用 $user = User::where('email', '=', 'user@user.com');
重新加载模型,那么当模型获取 ID 时它会工作得很好。
希望这对以后的其他人有所帮助!
我试图在 Laravel 8 中建立一个简单的多对多关系,但我 运行 遇到了一个奇怪的问题。我正在建立相当标准的 User/Roles 关系,但有一个区别:我在这两个 table 上的主键是 UUID 而不是整数。
没有任何错误,但是当我将角色附加到具有 $user->roles()->attach($userRole);
的用户时,保存在 role_user
链接 table 中的数据丢失了 user_id
, role_id
被正确插入。我最初遇到 role_id
也没有保存的问题,但我发现这是在模型上指定 protected $keyType = 'string';
。
我无法解决的是,这是我使用 UUID 造成的,还是我做了其他根本错误的事情。
用户模型
class User extends Authenticatable
{
use HasFactory, Notifiable;
protected $primaryKey = 'id';
protected $keyType = 'string';
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
protected static function boot()
{
parent::boot();
self::creating(function ($model) {
$model->id = (string)Str::uuid();
});
}
public function roles()
{
return $this->belongsToMany('App\Models\Role')
->using('App\Models\RoleUser');
}
}
角色用户模型
class RoleUser extends Pivot
{
use HasFactory;
protected $primaryKey = 'id';
protected $keyType = 'string';
protected static function boot()
{
parent::boot();
self::creating(function ($model) {
$model->id = (string)Str::uuid();
});
}
}
我在数据库中得到的结果如下。
用户/角色分配代码
$adminRole = Role::where('name', 'admin')->first();
$userRole = Role::where('name', 'user')->first();
$admin = User::create(['name' => 'Admin User', 'email' => 'admin@myapp.com', 'password' => Hash::make('adminpass')]);
$admin->save();
$user = User::create(['name' => 'User User', 'email' => 'user@myapp.com', 'password' => Hash::make('userpass')]);
$user->save();
$admin->roles()->attach($adminRole);
$user->roles()->attach($userRole);
$user->save();
$admin->save();
我真的迷路了,可能是因为我是 Laravel 的新手。
因此,如果其他人遇到上述问题,我找到的解决方案是:
在迁移中构建 table 时,确保将 uuid 设置为主! $table->uuid('id')->primary();
所有模型都应该设置如下:
protected $primaryKey = 'id';
protected $keyType = 'string';
public $incrementing = false;
以上组合似乎解决了我的问题。它似乎正在构建用户模型但没有为其分配 UUID(尽管它已保存在数据库中)。如果我只是使用 $user = User::where('email', '=', 'user@user.com');
重新加载模型,那么当模型获取 ID 时它会工作得很好。
希望这对以后的其他人有所帮助!