Laravel和BelongsTo和UUIDS在同一模型上的多对多关系



如何使多对多关系与UUIDS一起工作,并且一个表具有额外的belongsTo关系

我有两个表,usersprojects,其中user can have many projectsproject can have many users, where the project belongsTo a user

然而,当同一个用户存在于中间时,尽管被分配到了一个全新的项目,但我的中间表给出了error: unique key violation

用户

# Migration
Schema::create('users', function (Blueprint $table) {
$table->uuid('id')->primary()->default(Str::uuid());
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
# Users Model 
use IlluminateDatabaseEloquentConcernsHasUuids;
class User extends Authenticatable
{
use HasUuids, HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
// 1-Many
public function projects()
{
return $this->hasMany(Project::class);
}
}

项目

# Migration
Schema::create('projects', function (Blueprint $table) {
$table->uuid('id')->primary()->default(Str::uuid());
$table->string('name');
$table->timestamps();
$table->foreignUuid('user_id');
});
# Projects Model
use IlluminateDatabaseEloquentConcernsHasUuids;
class Project extends Model
{
use HasUuids, HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
];
/**
* The users that belong to the project.
*/
public function users()
{
return $this->belongsToMany(User::class, 'project_users');
}
// Inverse
public function user()
{
return $this->belongsTo(User::class);
}
}

中间表

# Migration
Schema::create('project_users', function (Blueprint $table) {
$table->uuid('id')->primary()->default(Str::uuid());
$table->timestamps();
# Whether set to using uuid or foreign uuid, both give same error.
$table->foreignUuid('user_id');
$table->foreignUuid('project_id');
});

上面的代码应该允许我创建一个新用户。创建一个新项目,将用户设置为项目所有者,并将他们设置为项目的用户。然后将其他项目也添加到项目中。

然而,一旦我将用户附加到第二个项目,我的中间表就会给出以下错误:SQLSTATE[23505]: Unique violation: 7 ERROR: duplicate key value violates unique constraint "project_users_pkey" DETAIL: Key (id)=(33a6d0b1-6602-4bc1-8da5-371d23109f22) already exists.

这没有意义,因为我将用户附加到一个完全不同的项目,而不是同一个旧项目。

Test via routes in web.php
# Runs fine the first time with expected behaviour. New project gets created, the project owner is set to the current user and the project adds the current user to the list of project users. 
# The second time it gives the unique key violation error, despite the second time creating a new project. 
Route::get('/', function () {
// Get first user
$user = User::all()[0];
$project = new Project([
'name' => 'Test Project 1',
]);
// Set the current user to be the owner of the project
$project->user()->associate($user);
$project->save();
// Add existing user to the list of users in that project
$serverGroup->users()->attach($user);
$serverGroupUsers = $serverGroup->users;
return [
'User' => $user,
'Server Group' => $serverGroup,
'Server Group Users' => $serverGroupUsers,
];
});

版本

PHP:8.1Laravel 9.19

因此,根据github问题中的注释,UUID id或多或少没有像它应该的那样自动生成。所以我想我试图插入一行,其中uuid总是设置为用户的ID。这就是为什么我得到了非唯一的uuid错误。

实际上,每次我想将用户附加到项目时,都需要手动创建一个新的UUID并进行设置。

$project->users()->attach($user, [ 'id' => Str::uuid()->toString()]);

之后,我的$user->projects显示用户拥有的所有项目,$projects->users显示项目拥有的所有用户。

我希望Laravel首先将他们的示例更新为UUID,而不是递增ID。或者至少有一些关于UUID的章节,介绍了它们所有雄辩的东西。我希望这能帮助其他需要UUIDS的可怜灵魂。

最新更新