每当 laravel 中发生记录插入或更新时,在数据透视表 table 中设置一个字段

set a field in pivot table whenever a record insert or update happens in laravel

好的,最近我正在laravel实现一个基于RBAC的系统。

我有这两个 classes 作为我的模型:

class User extends Authenticatable
{
    public function roles(){
        return $this->belongsToMany(\App\Role::class, 'user_role', 'user_id', 'role_id')->withPivot('is_expired', 'assigned_at', 'expire_at');
    }
}

class Role extends Model
{
    public function users(){
        return $this->belongsToMany(\App\User::class, 'user_role', 'role_id', 'user_id')->withPivot('is_expired', 'assigned_at', 'expire_at');
    }
}

它工作正常但是,我想根据 Role 模型的属性为枢轴 table 的 expire_at 属性设置默认值。例如,我在 Roles table 上有一个 period 属性,它是一个代表月数的数字。 所以我想当一个角色分配给一个用户(插入数据透视 table)时 expire_at 的值设置为 currentDatetime + thePeriodNum 个月并保存在数据透视 table.[=21 中=]

我怎样才能做到这一点?

我已经尝试了 laravel 自定义枢轴 class 和修改器,但它似乎不起作用或者我做错了什么。 有人提到在使用 attach()/detach() 方法时不会触发突变器,所以我认为即使它在工作,我也看不出有什么不同。 有人提到它可能与观察者有关,但我不知道什么是观察者,我是菜鸟。

就是这样,如果有人能帮助我度过我现在所处的困境,那对我来说真的很好。 提前致谢。

可以附加新角色并同时设置expires_at列。这将避免需要在您的代码中使用观察者(模型事件的侦听器)。

代码如下所示:

$role = Role::find($roleId);

$expireAt = now()->addMonths($role->period)->toDateTimeString();

// or Carbon::now()->addMonths($role->period)->toDateTimeString();

User::find($userId)->roles()->attach($role->id, ['expire_at' => $expireAt]);

到这里,角色找到了。时间戳是通过获取当前时间,添加基于角色的period(这应该是一个整数值)的额外月份来创建的。

最后,这被添加到用户角色的附件中。

添加为模型方法

这都可以作为 function/method 添加到 User 模型上,这样可以将代码清理成一个动作,->addRole($roleId):

// Within App\User.php

public function addRole($roleId)
{
    $role = \App\Role::find($roleId);

    $expiresAt = now()->addMonths($role->period)->toDateTimeString();

    $this->roles()->attach($role->id, [ 'expire_at' => $expiresAt ]);
}

然后可以通过以下方式调用它:

$user = User::find($id);

$user->addRole($roleId);

希望对您有所帮助。