LaravelTraining3(CRUD アプリケーション作成)


前回作成した PersonModel を利用して、社員管理 CRUD アプリをつくる

## migration

画面作成に当たって Person の項目を追加する

-   Email アドレス
-   生年月日
-   役職者フラグ
-   給与

下記コマンドでカラム追加用の migration ファイルを作成する

```
php artisan make:migration add_column_persons_table --table=persons
```

作成された migration ファイルを見てみる

```php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddColumnPersonsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('persons', function (Blueprint $table) {
            //
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('persons', function (Blueprint $table) {
            //
        });
    }
}
```

この時`upメソッド`に追加変更を追加し、元に戻す操作を`downメソッド`に書く
今回追加する項目を up/down メソッドに実装する

```php
    public function up()
    {
        Schema::table('persons', function (Blueprint $table) {
            $table->string('email');
            $table->date('birthday');
            $table->boolean('is_manager');
            $table->integer('saraly');
        });
    }

    public function down()
    {
        Schema::table('persons', function (Blueprint $table) {
            $table->dropColumns('email');
            $table->dropColumns('birthday');
            $table->dropColumns('is_manager');
            $table->dropColumns('saraly');
        });
    }

```

string や boolean などのカラムタイプや、
カラムの順序を変更するカラム修飾子については[こちら】(https://readouble.com/laravel/5.7/ja/migrations.html)
を参考に実装する

`php artisan migrate`でマイグレーションするが、以前データを登録している場合
NOT NULL 制約によって例外が発生する

```bash
 Illuminate\Database\QueryException  : SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect date value: '0000-00-00' for column 'birthbay' at row 1
 (SQL: alter table `persons` add `email` varchar(255) not null, add `birthbay` date not null, add `is_manager` tinyint(1) not null, add `saraly` int not null)
```

なのでいったん Rollback してから migrate する
`php artisan migrate:refresh`ですべての migrate を Rollback してから migrate する

```bash
laradock@4e1a9be4e777:/var/www$ php artisan migrate:refresh
Rolling back: 2019_04_03_075916_create_persons_table
Rolled back:  2019_04_03_075916_create_persons_table
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back:  2014_10_12_100000_create_password_resets_table
Rolling back: 2014_10_12_000000_create_users_table
Rolled back:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table
Migrating: 2019_04_03_075916_create_persons_table
Migrated:  2019_04_03_075916_create_persons_table
Migrating: 2019_04_17_045926_add_column_persons_table
Migrated:  2019_04_17_045926_add_column_persons_table
```

## Controller 作成

Persons を扱うリソースコントローラを作成する
`php artisan make:controller PersonController --resource`で
典型的な CRUD を実装するテンプレートコントローラを作成できる
https://readouble.com/laravel/5.7/ja/controllers.html

``` 
php ./app/Http/Controller/PersonController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PersonController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}

```

またルーターに追記する

```php ./routes/web.php
Route::resource('persons', 'PersonController');
```

`resouceメソッド`は初めて出てくるが、これはコントローラの各メソッドにワンライナーでルーティングしてくれるもの
`php artisan route:list`でルーティング一覧を確認してみる

```bash

laradock@4e1a9be4e777:/var/www$ php artisan route:list
+--------+-----------+------------------------+------------------+------------------------------------------------------------------------+--------------+| Domain | Method    | URI                    | Name             | Action                                                                 | Middleware   |
+--------+-----------+------------------------+------------------+------------------------------------------------------------------------+--------------+|        | GET|HEAD  | api/user               |                  | Closure                                                                | api,auth:api |
|        | GET|HEAD  | home                   | home             | App\Http\Controllers\HomeController@index                              | web,auth     |
|        | POST      | login                  |                  | App\Http\Controllers\Auth\LoginController@login                        | web,guest    |
|        | GET|HEAD  | login                  | login            | App\Http\Controllers\Auth\LoginController@showLoginForm                | web,guest    |
|        | POST      | logout                 | logout           | App\Http\Controllers\Auth\LoginController@logout                       | web          |
|        | POST      | password/email         | password.email   | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail  | web,guest    |
|        | POST      | password/reset         | password.update  | App\Http\Controllers\Auth\ResetPasswordController@reset                | web,guest    |
|        | GET|HEAD  | password/reset         | password.request | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web,guest    |
|        | GET|HEAD  | password/reset/{token} | password.reset   | App\Http\Controllers\Auth\ResetPasswordController@showResetForm        | web,guest    |
|        | GET|HEAD  | persons                | persons.index    | App\Http\Controllers\PersonController@index                            | web          |
|        | POST      | persons                | persons.store    | App\Http\Controllers\PersonController@store                            | web          |
|        | GET|HEAD  | persons/create         | persons.create   | App\Http\Controllers\PersonController@create                           | web          |
|        | GET|HEAD  | persons/{person}       | persons.show     | App\Http\Controllers\PersonController@show                             | web          |
|        | PUT|PATCH | persons/{person}       | persons.update   | App\Http\Controllers\PersonController@update                           | web          |
|        | DELETE    | persons/{person}       | persons.destroy  | App\Http\Controllers\PersonController@destroy                          | web          |
|        | GET|HEAD  | persons/{person}/edit  | persons.edit     | App\Http\Controllers\PersonController@edit                             | web          |
|        | POST      | register               |                  | App\Http\Controllers\Auth\RegisterController@register                  | web,guest    |
|        | GET|HEAD  | register               | register         | App\Http\Controllers\Auth\RegisterController@showRegistrationForm      | web,guest    |
+--------+-----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
```

## 社員一覧実装

### PersonController/index メソッドを実装する

```php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
// Modelのimport
use App\Person;

class PersonController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        // 全件取得
        $persons = Person::all();
        return view('persons.index', ['persons' => $persons]);
    }
```

### view の実装

resource/view に`persons`ディレクトリを作成

```./resouces/persons/index.blade.php
@extends('layouts.app')

@section('content')
<div class="container">
    <h1>社員一覧画面</h1>
    <div class="table-responsive">
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>{{ __('ID') }}</th>
                    <th>{{ __('姓') }}</th>
                    <th>{{ __('名') }}</th>
                    <th>{{ __('Email') }}</th>
                </tr>
            </thead>
            <tbody>
            @foreach ($persons as $person)
                <tr>
                    <td>{{ $person->id }}</td>
                    <td>{{ $person->last_name }}</td>
                    <td>{{ $person->first_name }}</td>
                    <td>{{ $person->email }}</td>
                </tr>
            @endforeach
            </tbody>
        </table>
    </div>
</div>
@endsection
```

localhost/persons にアクセスしてみる

### seeder の利用

データがないので`seeder`を利用してデータを投入してみる
`php artisan make:seeder PersonsTableSeeder`で作成

```.\database\seeds\PersonsTableSeeder.php
<?php

use Illuminate\Support\Str;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class PersonsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {

        DB::table('persons')->insert([[
            'first_name' => 'Ubiba',
            'last_name' => 'Vitual',
            'email' => Str::random(10).'@mail.com',
            'saraly' => rand(200000, 500000),
            'is_manager'=> true ,
            'birthday' => Carbon::createFromDate(rand(1950, 2010), rand(1,12), rand(1, 28))->format('Y-m-d'),
            'created_at' => Carbon::now(),
            'updated_at' => Carbon::now()
        ],[
            'first_name' => 'Mememe',
            'last_name' => 'Mokota',
            'email' => Str::random(10).'@mail.com',
            'saraly' => rand(200000, 500000),
            'is_manager'=> false ,
            'birthday' => Carbon::createFromDate(rand(1950, 2010), rand(1,12), rand(1, 28))->format('Y-m-d'),
            'created_at' => Carbon::now(),
            'updated_at' => Carbon::now()
        ]]);
    }
}

```

`composer dump-autoload` してから
`php artisan db:seed --class=PersonsTableSeeder`で登録

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177957/2ad819e6-fe04-3b62-ccf5-e973d2e02f90.png)

## 社員詳細の実装

一覧画面の ID をクリックすると詳細画面に飛ぶようにする

```
                <tr>
                    <!-- <td>{{ $person->id }}</td> -->
                    <td><a href="{{ url('persons/'.$person->id) }}"</a>{{ $person->id }}</td>
                    <td>{{ $person->last_name }}</td>
                    <td>{{ $person->first_name }}</td>
                    <td>{{ $person->email }}</td>
                </tr>
```

### show メソッドの実装

```
    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $person = Person::find($id);
        return view('persons.show', ['person' => $person]);
    }
```

### showView の実装

```
@extends('layouts.app')

@section('content')
<div class="container">
    <h1>社員詳細画面</h1>
    <dl class="row">
        <dt class="col-md-2">{{ __('ID') }}:</dt>
        <dd class="col-md-10">{{ $person->id }}</dd>
        <dt class="col-md-2">{{ __('姓') }}:</dt>
        <dd class="col-md-10">{{ $person->last_name }}</dd>
        <dt class="col-md-2">{{ __('名') }}:</dt>
        <dd class="col-md-10">{{ $person->first_name }}</dd>
        <dt class="col-md-2">{{ __('生年月日') }}:</dt>
        <dd class="col-md-10">{{ $person->birthday }}</dd>
        <dt class="col-md-2">{{ __('Emailアドレス') }}:</dt>
        <dd class="col-md-10">{{ $person->email }}</dd>
        <dt class="col-md-2">{{ __('役職者') }}:</dt>
        <dd class="col-md-10">{{ $person->is_manager }}</dd>
        <dt class="col-md-2">{{ __('給与') }}:</dt>
        <dd class="col-md-10">{{ $person->saraly }}</dd>
        <dt class="col-md-2">{{ __('Created') }}:</dt>
        <dd class="col-md-10">
            <time itemprop="dateCreated" datetime="{{ $person->created_at }}">
                {{ $person->created_at }}
            </time>
        </dd>
        <dt  class="col-md-2">{{ __('Updated') }}:</dt>
        <dd class="col-md-10">
            <time itemprop="dateModified" datetime="{{ $person->updated_at }}">
                {{ $person->updated_at }}
            </time>
        </dd>
    </dl>
    <div class="edit">
        <a href="{{ url('persons/'.$person->id.'/edit') }}" class="btn btn-primary">
            {{ __('更新') }}
        </a>
        <a href="{{ url('persons/'.$person->id.'/destloy') }}" class="btn btn-danger">
            {{ __('削除') }}
        </a>

    </div>

</div>
@endsection
```