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 时它会工作得很好。

希望这对以后的其他人有所帮助!