Laravel-admin TODO機能の作成②(CRUDまで)

#前回
[Laravel-admin TODO機能の作成①](https://qiita.com/ksri-soln/items/45caca66605f0bf1ce4d)

#テストデータの作成

###ユーザーを作成

[https://homestead.test/admin/auth/users](https://homestead.test/admin/auth/users)
にてdevユーザーを作成する

・ユーザーIDを【dev】
・権限を【All permission】
・上記以外の項目は適当に登録します
（役割のAdministratorはつけない）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413817/94d25d00-9522-163c-6972-fd95f5f13b02.png)

##Todoテーブルにデータを追加

###データ作成（create）

テスト検証用データとするので削除を簡単にするためユーザーを指定する。

```
php artisan make:seeder TodosTableSeeder
php artisan make:factory TodosFactory --model=Models/Todo
```

```devproject\database\seeds\TodosTableSeeder.php
<?php

use Illuminate\Database\Seeder;

class TodosTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //
        factory(App\Models\Todo::class, 100)->create();
    }
}
```

```devproject\database\factories\DevTodosFactory.php
<?php

/* @var $factory \Illuminate\Database\Eloquent\Factory */
use Faker\Generator as Faker;

$factory->define(App\Models\Todo::class, function (Faker $faker) {
    return [
        // devユーザーの指定
        'user_id' => function () {
            return config('admin.database.users_model')::where('username','dev')->first()->id;
        },
        'title' => $faker->unique()->name,
        'detail' => $faker->text(200)
    ];
});
```

###データ登録（insert）

```
php artisan db:seed --class=TodosTableSeeder
```

###データ確認

[https://homestead.test/admin/helpers/terminal/database](https://homestead.test/admin/helpers/terminal/database)

```
select * from todos;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413817/a386c57b-7dad-2b0a-889e-f53b211e6f00.png)

※user_idが全て2(devユーザーのid)となっていること

###反省点
確認したわけではないので憶測だが、factoryクラスでdevユーザーを取得するSQLは100回データを作ると100回実行されているのではないか？
テストデータと言っても、無駄なSQLを大量に流したくないので時間があるときに検証する。
※ユーザーのIDが判明しているならばfactory部分に固定でuser_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) {
            $builder->where('user_id', auth('admin')->user()->id);
        });
    }

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

```

###Gridの修正

ユーザーIDではなくユーザー名を表示する

```devproject\app\Admin\Controllers\TodoController.php
    /**
     * Make a grid builder.
     *
     * @return Grid
     */
    protected function grid()
    {
        $grid = new Grid(new Todo);

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

        return $grid;
    }
```

###動作確認

[https://homestead.test/admin/todo](https://homestead.test/admin/todo)

ログインしているユーザーが【admin】の場合は表示されてないはずです。
ログアウトして、【dev】ユーザーでログインしてください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413817/694f5ddf-20b6-74dc-ee93-19c75e5317ae.png)

※adminでは表示なし

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413817/62785ccc-41da-95ac-cbc0-5f3854353e69.png)

【dev】ユーザーでは表示されていること

#新規登録処理の修正

###Formの修正

```devproject\app\Admin\Controllers\TodoController.php
use Illuminate\Validation\Rule;

    /**
     * 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) {
                    // ログインID単位で一意
                    $query->where('user_id', auth('admin')->user()->id);
                }),
            ];
        })->required(true);
        $form->textarea('detail', '詳細')->rules('required');
        $form->hidden('user_id');

        return $form;
    }
```

### storeの修正

```devproject\app\Admin\Controllers\TodoController.php
    public function store()
    {
        request()->merge(['user_id' => auth('admin')->user()->id]);

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

###反省点
Formフィールドにheddinでuser_idを置いているが、これを簡単に回避する方法がわからなかった。
ミドルウェアでRequestにuser_idを追加する方法もあるが、もっとシンプルにできるのではないか。もう少し勉強（ソースを読む）する。

#更新処理の修正

### updateの修正

```devproject\app\Admin\Controllers\TodoController.php
    public function update($id)
    {
        request()->merge(['user_id' => auth('admin')->user()->id]);

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

#動作検証
新規登録するとログインユーザーに正しく登録されていること
更新すると対象のデータのみ正しく更新されていること
削除すると対象のデータのみ正しく削除されていること
※画像を貼ると無駄にスクロールが増えるので割愛

#学んだこと
###Laravel
ヘルパ関数マジ便利すぎ。
欲しいデータや機能があるときはまずヘルパ関数を調べるといいと思います。
[ヘルパ 5.8 Laravel](https://readouble.com/laravel/5.8/ja/helpers.html)
###Laravel-admin
laravel-adminは機能が多すぎてまだまだ慣れが必要そうです。
CRUDを作るといいながらユーザー名のリレーション部分を除けば既に実装されています。便利過ぎて逆に戸惑いました。
その分、基礎を学ぶことも多いですが。（気が緩むとすぐガリガリ書きたくなるので、ちゃんと調べるのに苦労する）

#課題
1. roleによってユーザーを全て表示する機能の実装
2. detailメソッドの修正
3. gridに実装されている機能全般
4. ブラウザテスト、httpテスト、phpunitのテスト実装

などなど・・・

#次回

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