【laravel-admin】deleteアクションをカスタマイズする


デフォルトのdeleteアクションだと特定の条件だけ削除したい場合や、条件によって確認メッセージを変えたい場合に対応できない。
リレーションを貼ってあるテーブルでリレーション元が消えちゃうとまずい場合とか。

そのためカスタマイズする必要がある。実際はカスタマイズじゃなく、オリジナルの削除処理を実装してそっちを使う。

カスタムアクションを作る

php artisan admin:action Post\\Delete --grid-row --name="delete"

以下のディレクトリに作られる
app/Admin/Actions/Post/Delete.php

<?php

namespace App\Admin\Actions\Post;

use Carbon\Carbon;
use Encore\Admin\Actions\RowAction;

class Delete extends RowAction
{
    public $name = 'delete';

    public function handle()
    {
        // 削除処理
        $this->row->delete();

        return $this->response()->success('Delete Successful')->refresh();
    }

    public function dialog()
    {
        $auths = $this->row->auths;
        $auths = $auths->filter(function($el){
            $now = Carbon::now();
            return $now < $el->auth_expired;
        });
        if(empty($auths->toArray()))
        {
            $message = '削除しますか?';
        }
        else
        {
            $message = '認証済みのようです。本当に削除しますか?';
        }

        $this->confirm($message);
    }

}

postsテーブルにauthsテーブルが紐づいていて、認証済みだった場合にメッセージを切り替える例。
中身の処理は適宜変更してください。
完全に削除自体を禁止することも可能。

public function dialog()
{
...
}

dialog() を使うと確認ダイアログが出せます。
こういうの↓

public function form()
{
  $type = [
        1 => 'Advertising',
        2 => 'Illegal',
        3 => 'Fishing',
    ];

  $this->checkbox('type', 'type')->options($type);
  $this->textarea('reason', 'reason')->rules('required');
}

form() を使って何らかの入力や選択をさせることもできます。
AWSみたいに「削除」と文字列を送らないと削除させないとか。

作ったカスタムアクションを使うように設定

最後に作ったカスタムアクションを使用するように設定していきます。
合わせてデフォルトの削除アクションはdisabledに変更します。

<?php

namespace App\Admin\Controllers;

use App\Admin\Actions\Post\Delete;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;

class PostController extends AdminController
{
    ...

    /**
     * Make a grid builder.
     *
     * @return Grid
     */
    protected function grid()
    {
        ...
        $grid->actions(function ($actions) {
            $actions->disableDelete(); // オリジナルの削除は非表示
            $actions->add(new Delete);
        });
        ...

        return $grid;
    }

まとめ

結構自由度高くカスタムアクション作れるので、便利ですね。
通常はデフォルトで用意されているdeleteアクションを使えばいいと思いますが、特殊なケースではカスタムアクションを作っていけば問題なさそう。