Дата публикации: 02.03.2025 в 07:04

Soft Deleting в MoonShine v3+

Анатолий ШевелевАнатолий Шевелев
1 комментария

Данная статья является адаптацией предыдущей статьи для MoonShine v3 и выше.

Рекомендую предварительно изучить соответствующий раздел документации Laravel и подготовить модель к реализации функции "мягкого удаления".

Инструкция для быстрой реализации Soft Deleting в MoonShine:

1. В ресурсе добавляем QueryTagдля того, чтобы быстро применять фильтр только удалённых записей.

public function queryTags(): array
{
    return [
        QueryTag::make('Deleted', fn(Builder $q) => $q->onlyTrashed())
    ];
}

2. Опционально, но может пригодится - добавляем возможность просмотра удаленных записей (иначе нас ждет 404 страница).

protected function modifyItemQueryBuilder(
    Builder $builder
): Builder
{
    return $builder->withTrashed();
}

3. Добавляем кнопки для восстановления удаленных записей и удаления. Не будем перегружать гайд кодом и реализуем в режиме async ресурса. Также самостоятельно вы можете продублировать их в остальных методах.

protected function indexButtons(): ListOf
{
    return parent::indexButtons()
        ->prepend(
            ActionButton::make('Restore')
                ->method(
                    'restore',
                    events: [$this->getListEventName()]
                )
                ->canSee(
                    fn(Article $model) => $model->trashed()
                ),

            ActionButton::make('Force delete')
                ->method(
                    'forceDelete',
                    events: [$this->getListEventName()]
                )
                ->canSee(
                    fn(Article $model) => $model->trashed()
                ),
        );
}

Соответственно если не async то вам необходимо создать ендпоинты и реализовать восстановление и удаление самостоятельно, останется только указать урл у кнопок

Также при необходимости вы можете добавить withConfirm и сделать тоже самое но внутри через FormBuilder и метод asyncMethod.

4. Собственно реализация методов удаления и восстановления. Если пойдете путем своего контроллера, то тоже самое будет в нем.

public function restore(
    MoonShineRequest $request
): MoonShineJsonResponse
{
    $item = $request->getResource()->getItem();
    $item->restore();

    return MoonShineJsonResponse::make()
        ->toast('Success');
}

public function forceDelete(
    MoonShineRequest $request
): MoonShineJsonResponse
{
    $item = $request->getResource()->getItem();
    $item->forceDelete();

    return MoonShineJsonResponse::make()
        ->toast('Success');
}

5. Давайте также наведем красоту и скроем кнопку удаления и массового удаления на странице с активным QueryTag.

protected function modifyDeleteButton(
    ActionButtonContract $button
): ActionButtonContract
{
    return $button->canSee(
        fn(Article $model) => !$model->trashed()
    );
}

protected function modifyMassDeleteButton(
    ActionButtonContract $button
): ActionButtonContract
{
    return $button->canSee(
        fn() => request()->input('query-tag') !== 'deleted'
    );
}

Готово!

Комментарии (1)

Евгений
Евгений
03.03.2025 в 17:23
Хорошо что теперь есть статья! Можно просто гуглить решение и быстро его найти)
Анатолий
Анатолий
03.03.2025 в 17:40
Я того же мнения :)
ОбщайсяРазвивайсяУчисьРаботай
ОбщайсяРазвивайсяУчисьРаботай
ОбщайсяРазвивайсяУчисьРаботай
ОбщайсяРазвивайсяУчисьРаботай