简体   繁体   中英

Laravel Eloquent many-to-many not saving key

I'm attempting to build a simple many-to-many relationship in Laravel 8 but I'm running into an odd problem. I'm building the fairly standard User/Roles relationship but with one difference: my primary key on those two tables is a UUID rather than an integer.

There aren't any errors but when I attach a role to a user with $user->roles()->attach($userRole); the data saved in the role_user linking table is missing the user_id , the role_id is inserted correctly. I originally had a problem where the role_id wasn't saving either but I worked out that was down to specifying protected $keyType = 'string'; on the models.

What I can't work out is if this is being caused by me using UUID's or I've done something else fundamentally wrong.

User Model

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');
    }
}

RoleUser Model

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();
        });
    }
}

What I end up with, in the DB is the following.

数据库结果

User / Role assignment code

    $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();

I'm really lost here, possibly because I'm new to Laravel.

So if anybody else runs into the above issue the solution I found was to:

When building the table in the migration make sure to set the uuid as primary! $table->uuid('id')->primary();

And the models should all be setup as follows:

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

That above combination seems to have resolved my issue. It seemed to be building the User model but not assigning it's UUID (despite it being saved in the database). If I were to simply reload the model using $user = User::where('email', '=', 'user@user.com'); it would then work perfectly fine as the model picked up the ID.

Hopefully this helps somebody else out in the future!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM