Laravel-admin TODO機能の作成④

#前回
[Laravel-admin TODO機能の作成③(grid)
](https://qiita.com/ksri-soln/items/858aeeb63676ad4cbb8b)

#役割がadministratorの場合の処理

役割によって表示、操作できる内容の修正をします。

###modelを修正

グローバルスコープでユーザー自身としているのをadministratorの場合は解除。

```devproject\app\Models\Todo.php
        static::addGlobalScope('user_id', function (Builder $builder) {
            if (!auth('admin')->user()->isAdministrator()) {              //追加
                $builder->where('user_id', auth('admin')->user()->id);
            }                                                             //追加
        });
```

###gridを修正

ユーザー名表示をadministratorの場合のみにします
（ユーザー自身のみの場合に全て自分のユーザー名が表示されるのは邪魔なので）

```devproject\app\Admin\Controllers\TodoController.php
        if (auth('admin')->user()->isAdministrator()) {
            $grid->user()->name('ユーザー名')->style('min-width:100px;');
        }
```

###gridのfilterを修正

administratorの場合はユーザー名検索を入れます。

```devproject\app\Admin\Controllers\TodoController.php
                if (auth('admin')->user()->isAdministrator()) {
                    $filter->where(function ($query) {
                        $query->whereHas('user', function ($query) {
                            $query->where('name', 'like', "%{$this->input}%");
                        });
                    }, 'ユーザー名');
                }
```

###画面

devユーザーの場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413817/ab025182-b708-4b5b-a440-53e97318d9ec.png)

adminユーザーの場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413817/efe1b55d-bf67-95ec-603e-c17a86a871d6.png)

#showについて

新参な機能のようで、gridやformに比べるとまだまだ発展途上な感じがします。
リレーション先のデータも表示、編集、削除画面に遷移できるのが良い。

```devproject\app\Admin\Controllers\TodoController.php
    /**
     * Make a show builder.
     *
     * @param mixed $id
     * @return Show
     */
    protected function detail($id)
    {
        $show = new Show(Todo::findOrFail($id));

        $show->id('ID');
        $show->user('ユーザー名')->as(function ($user) {
            return $user->name;
        });
        $show->title('タイトル');
        $show->detail('詳細');
        $show->created_at('Created at');
        $show->updated_at('Updated at');

        $show->user('ユーザー情報', function ($user) {
            $user->setResource('/admin/auth/users');
            $user->id('ユーザーID');
            $user->name('ユーザー名');
        });

        return $show;
    }
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413817/57a6468e-1092-3ba3-427b-97b92fc38bdd.png)

#各画面のheaderとdescriptionについて

表示したい名前を付けるだけです。
↓はindexを修正した場合。

```devproject\app\Admin\Controllers\TodoController.php
    /**
     * Index interface.
     *
     * @param Content $content
     * @return Content
     */
    public function index(Content $content)
    {
        return $content
            ->header('TODO一覧')
            ->description('一覧を表示してます')
            ->body($this->grid());
    }
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413817/b5e6c068-2524-2d7e-070c-df3302df8fd3.png)


#ファイル出力について

デフォルトではCSVファイルが出力されます。
エクセル出力にしたい場合は[公式](https://laravel-admin.org/docs/#/en/model-grid-export)

カスタマイズはまたの機会にでも。

#コード
この時点でのソースコード

###コントローラ

```devproject\app\Admin\Controllers\TodoController.php
<?php

namespace App\Admin\Controllers;

use App\Models\Todo;
use App\Http\Controllers\Controller;
use Encore\Admin\Controllers\HasResourceActions;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Show;
use Illuminate\Validation\Rule;
use Encore\Admin\Widgets\Table;

class TodoController extends Controller
{
    use HasResourceActions;

    /**
     * Index interface.
     *
     * @param Content $content
     * @return Content
     */
    public function index(Content $content)
    {
        return $content
            ->header('TODO一覧')
            ->description('一覧を表示してます')
            ->body($this->grid());
    }

    /**
     * Show interface.
     *
     * @param mixed $id
     * @param Content $content
     * @return Content
     */
    public function show($id, Content $content)
    {
        return $content
            ->header('TODO詳細')
            ->description('詳細を表示してます')
            ->body($this->detail($id));
    }

    /**
     * Edit interface.
     *
     * @param mixed $id
     * @param Content $content
     * @return Content
     */
    public function edit($id, Content $content)
    {
        return $content
            ->header('TODO編集')
            ->description('編集を表示してます')
            ->body($this->form()->edit($id));
    }

    /**
     * Create interface.
     *
     * @param Content $content
     * @return Content
     */
    public function create(Content $content)
    {
        return $content
            ->header('TODO登録')
            ->description('登録を表示してます')
            ->body($this->form());
    }

    /**
     * Make a grid builder.
     *
     * @return Grid
     */
    protected function grid()
    {
        $grid = new Grid(new Todo);

        $grid->id('ID')->modal('情報', function () {

            $data = [
                [
                    $this->id,
                    $this->user->name,
                    $this->title,
                    $this->detail,
                ]
            ];

            return new Table(['ID', 'ユーザー名', 'タイトル', '詳細'], $data);
        })->sortable();

        if (auth('admin')->user()->isAdministrator()) {
            $grid->user()->name('ユーザー名')->style('min-width:100px;');
        }
        $grid->title('タイトル')->setAttributes(['style' => 'background-color:#ffdbdb;'])->editable();
        $grid->detail('詳細')->limit(20)->expand(function () {
            return $this->detail;
        });
        $grid->created_at('Created at')->label('danger');
        $grid->updated_at('Updated at')->badge();

        $grid->filter(function ($filter) {
            $filter->column(1/2, function ($filter) {
                $filter->disableIdFilter();
                $filter->startsWith('title','タイトル');
                $filter->between('created_at', '登録日時')->datetime();
            });
            $filter->column(1/2, function ($filter) {
                $filter->contains('detail','詳細');
                if (auth('admin')->user()->isAdministrator()) {
                    $filter->where(function ($query) {
                        $query->whereHas('user', function ($query) {
                            $query->where('name', 'like', "%{$this->input}%");
                        });
                    }, 'ユーザー名');
                }
            });
        });

        return $grid;
    }

    /**
     * Make a show builder.
     *
     * @param mixed $id
     * @return Show
     */
    protected function detail($id)
    {
        $show = new Show(Todo::findOrFail($id));

        $show->id('ID');
        $show->user('ユーザー名')->as(function ($user) {
            return $user->name;
        });
        $show->title('タイトル');
        $show->detail('詳細');
        $show->created_at('Created at');
        $show->updated_at('Updated at');

        $show->user('ユーザー情報', function ($user) {
            $user->setResource('/admin/auth/users');
            $user->id('ユーザーID');
            $user->name('ユーザー名');
        });

        return $show;
    }

    /**
     * Make a form builder.
     *
     * @return Form
     */
    protected function form()
    {
        $form = new Form(new Todo);

        $form->text('title', 'タイトル')->rules(function ($form) {
            return [
                'required',
                Rule::unique('todos')->where(function($query) {
                    $query->where('user_id', auth('admin')->user()->id);
                }),
            ];
        })->required(true);
        $form->textarea('detail', '詳細')->rules('required');
        $form->hidden('user_id');

        return $form;
    }

    public function store()
    {
        request()->merge(['user_id' => auth('admin')->user()->id]);

        return $this->form()->store();
    }

    public function update($id)
    {
        request()->merge(['user_id' => auth('admin')->user()->id]);

        return $this->form()->update($id);
    }
}
```

###モデル

```devproject\app\Models\Todo.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class Todo extends Model
{
    /**
     * モデルの「初期起動」メソッド
     *
     * @return void
     */
    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope('user_id', function (Builder $builder) {
            if (!auth('admin')->user()->isAdministrator()) {
                $builder->where('user_id', auth('admin')->user()->id);
            }
        });
    }

    /**
     * ユーザーに関連する情報を取得
     */
    public function user()
    {
        return $this->hasOne(config('admin.database.users_model'), 'id', 'user_id');
    }
}
```

#次回
テスト関連をやってみようと思います。