【问题标题】:Laravel Eloquent many-to-many not saving keyLaravel Eloquent 多对多不保存密钥
【发布时间】:2021-02-02 18:39:45
【问题描述】:

我试图在 Laravel 8 中建立一个简单的多对多关系,但我遇到了一个奇怪的问题。我正在构建相当标准的用户/角色关系,但有一个区别:我在这两个表上的主键是 UUID 而不是整数。

没有任何错误,但是当我使用$user->roles()->attach($userRole); 将角色附加到用户时,role_user 链接表中保存的数据缺少user_idrole_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 的新手。

【问题讨论】:

  • 如果您使用字符串作为主键,请确保还将$incrementing 设置为false ...您能否提供您调用$user->roles()->attach(...)的代码
  • role_user迁移中的user_id是一个什么样的字段?
  • 你需要删除 protected $ keyType = 'string';因为这使用 if 主键字符串,但在你的情况下使用 id (integer)
  • @Abdulmajeed 当我的主键是字符串时,为什么我需要这样做?我没有使用整数,我使用的是 UUID
  • @IGP 我的 role_user 迁移看起来像这样,所以 role_id 和 user_id 都是 UUID 的 Schema::create('role_user', function (Blueprint $table) { $table->uuid('id' ); $table->uuid('role_id'); $table->uuid('user_id'); $table->timestamps(); });

标签: php laravel eloquent many-to-many laravel-8


【解决方案1】:

因此,如果其他人遇到上述问题,我找到的解决方案是:

在迁移中构建表时,请确保将 uuid 设置为主! $table->uuid('id')->primary();

所有的模型都应该设置如下:

protected $primaryKey = 'id';
protected $keyType = 'string';
public $incrementing = false;

上述组合似乎解决了我的问题。它似乎正在构建用户模型,但没有分配它的 UUID(尽管它被保存在数据库中)。如果我只是使用$user = User::where('email', '=', 'user@user.com'); 重新加载模型,那么它会在模型​​获取 ID 时完美运行。

希望这可以帮助将来的其他人!

【讨论】:

    猜你喜欢
    • 2017-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 2022-01-12
    • 2015-03-21
    • 1970-01-01
    相关资源
    最近更新 更多