来自 Enum 强制转换列的预先加载关系返回错误

Eager loading relationship from an Enum casted column returns error

提问人:Kenneth 提问时间:10/21/2023 最后编辑:Kenneth 更新时间:10/22/2023 访问量:76

问:

我创建了 RoleEnum 并将其转换为用户模型。强制转换为 RoleEnum 的role_id也与 Role model 有关系。

<?php

namespace App\Enums;

enum RoleEnum:int
{
    case SYSTEM_ADMINISTRATOR = 1;
    case ADMINISTRATOR = 2;
    case SAMPLE_ROLE_ONE = 3;
    case SAMPLE_ROLE_TWO = 4;
    case SAMPLE_ROLE_THREE = 5;
    case SAMPLE_ROLE_FOUR = 6;
}

用户模型

protected $casts = [
    'email_verified_at' => 'datetime',
    'password' => 'hashed',
    'role_id' => RoleEnum::class,
];

public function role(): BelongsTo
{
    return $this->belongsTo(Role::class);
}

在我的控制器索引

$users = User::with('role')
    ->paginate()
    ->withQueryString();

我收到这个错误,它指向 paginate()。它必须使用类而不是值。

Object of class App\Enums\RoleEnum could not be converted to string

编辑:经过进一步测试,我发现该错误是由急切加载角色引起的,该角色是 Enum 强制转换列,而不是由 paginate() 引起的。我可以简单地删除枚举转换,一切都会正常工作。但是有没有办法强制转换枚举并仍然使用预先加载呢?

Laravel 枚举急 切加载

评论


答:

0赞 mrvivaldio 10/22/2023 #1

我建议您创建一个包含字段 id、name、slug、level 的角色表 迁移应如下所示

public function up(): void
{
    Schema::create('roles', function (Blueprint $table) {
        $table->id();
        $table->string('slug')->unique();
        $table->string('name');
        $table->unsignedTinyInteger('level');
        $table->timestamps();
        $table->softDeletes();
    });
}

和 users 表

public function up(): void
{
    Schema::create('users', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->unsignedTinyInteger('role_id')->index();
        $table->string('username')->unique();
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
        $table->softDeletes();
    });
}

您可以自由地个性化一切

然后,必须根据你想要的东西来管理模型上的关系,在这些示例中,用户只有一个角色,我放置了级别字段,以便以后能够确定你的角色的优先级。

在“角色模型”中,放置以下行

public function users(){
     return $this->hasMany(User::class);
}

在“用户”模型中,放置以下行

public function role(){
     return $this->belongsTo(Role::class);
}

然后你可以做

$users = User::with('role')
     ->paginate(10)
     ->withQueryString();

评论

0赞 Kenneth 10/22/2023
我已经有一个角色表,每个用户只能有一个角色。问题在于在将role_id转换为枚举时急于加载角色。
0赞 mrvivaldio 10/23/2023
如果我理解正确,您想创建一个动态变化的角色吗?是的,为什么不修改用户,尽管这会用无用的查询轰炸您的网站。
0赞 Kenneth 10/23/2023
不。我已经有了这个功能。目标是,在使用预先加载的同时将role_id转换为枚举。急切加载似乎返回 RoleEnum 的实例而不是值。我已经更新了我的标题,并在问题中添加了我的发现。