Дата публикации: 20.06.2024 в 15:23

SoftDeletes в MoonShine

Danil ShutskyDanil Shutsky
2 комментария

Всем привет! Хочу расписать для вас инструкцию как быстро реализовать softDeletes в MoonShine

1. В ресурсе добавляем queryTag для того чтобы видеть удаленные записи

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

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

protected function resolveItemQuery(): Builder
{
    return parent::resolveItemQuery()->withTrashed();
}

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

public function indexButtons(): array
{
        return [
            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
{
        /** @var Article $item */
        $item = $request->getResource()->getItem();
        $item->restore();

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

public function forceDelete(MoonShineRequest $request): MoonShineJsonResponse
{
        /** @var Article $item */
        $item = $request->getResource()->getItem();
        $item->forceDelete();

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

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

public function getDeleteButton(
        ?string $componentName = null,
        string $redirectAfterDelete = '',
        bool $isAsync = true
): ActionButton {
        return parent::getDeleteButton($componentName, $redirectAfterDelete, $isAsync)
            ->canSee(fn(Article $model) => !$model->trashed());
}

public function getMassDeleteButton(
        ?string $componentName = null,
        string $redirectAfterDelete = '',
        bool $isAsync = true
): ActionButton {
        return parent::getMassDeleteButton($componentName, $redirectAfterDelete, $isAsync)
            ->canSee(fn() => request()->input('query-tag') !== 'deleted');
}

Вот и все! Вам останется немного навести красоты и добавить условий под свои кейсы

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

Александр
Александр
20.06.2024 в 18:16
Отличная статья! Спасибо большое за знания. Самому пришлось бы долго разбираться, ибо при попытке реализации мысль дальше п. 3 не пошла...
Анатолий
Анатолий
20.06.2024 в 17:24
Спасибо большое за такие вот статьи! У меня пока нет такой задачи, но пример выглядит круто, и я обязательно попробую проделать это своими руками ))
ОбщайсяРазвивайсяУчисьРаботай
ОбщайсяРазвивайсяУчисьРаботай
ОбщайсяРазвивайсяУчисьРаботай
ОбщайсяРазвивайсяУчисьРаботай