php Laravel多对多关系与属于和UUIDS在同一模型上

new9mtju  于 2022-10-30  发布在  PHP
关注(0)|答案(1)|浏览(127)

如何使用UUIDS获取多对多关系,并且一个表具有附加的belongsTo关系?

我有两个表,分别是usersprojects,其中一个是user can have many projects,另一个是project 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 Illuminate\Database\Eloquent\Concerns\HasUuids;

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 Illuminate\Database\Eloquent\Concerns\HasUuids;

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:文件系统相关扩展

1qczuiv0

1qczuiv01#

因此,基于github问题中的comments,或多或少UUID id没有自动生成。所以我想我试图插入一行,其中uuid总是设置为用户的ID。这就是为什么我得到了非唯一uuid错误。
实际上,我需要手动创建一个新的UUID,并在每次要将用户附加到项目时设置它。

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

之后,我的$user->projects显示用户拥有的所有项目,$projects->users显示项目拥有的所有用户。
我希望Laravel将他们的例子更新为UUID优先,而不是递增ID。或者至少有一些关于UUID的章节来描述他们所有雄辩的东西。我希望这能帮助其他一些需要UUID的可怜的灵魂。

相关问题