установить поле в сводной таблице всякий раз, когда вставка или обновление записи происходит в laravel - PullRequest
0 голосов
/ 13 октября 2019

ОК, недавно я внедряю систему на основе RBAC в laravel.

У меня есть два класса в качестве моих моделей:

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

все работает нормально, НО, я хочу установитьзначение по умолчанию для атрибута expire_at сводной таблицы на основе атрибута модели Role. например, у меня есть атрибут period в таблице Roles, и это число, представляющее количество месяцев. Поэтому я хочу, чтобы когда роли, назначенной пользователю (вставленной в сводную таблицу), значение expire_at было установлено на currentDatetime + thePeriodNum месяцы и сохранено в сводной таблице.

как мне этого добиться?

Я пробовал использовать классы и мутаторы laravel custom pivot, но, похоже, они не работают или я сделал что-то не так. кто-то упомянул, что мутаторы не запускаются при использовании методов attach() / detach(), поэтому я думаю, что даже если бы он работал, я не мог видеть разницу. Кто-то упомянул, что это возможно с наблюдателями, но я понятия не имею, что такое наблюдатель im noob.

Вот и все, было бы действительно хорошо, если бы кто-нибудь мог помочь мне преодолеть этот беспорядок, в котором я сейчас нахожусь. Заранее спасибо.

1 Ответ

0 голосов
/ 14 октября 2019

Можно добавить новую роль и одновременно установить столбец 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 (это должно быть целочисленное значение).

Наконец, это добавляется в прикрепление роли к пользователю. .

Добавить в качестве метода модели

Все это можно добавить как функцию / метод в модель 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);

Надеюсь, эта помощь.

...