laravelでwebアプリケーションを作ってみる 20181020

# モデルの保存・更新・削除
## 保存をできる様にする
Personモデルを下記を追記する。

```php5:Person.php
protected $guarded = array('id');

public static $rules = array(
    'name' => 'required',
    'mail' => 'email',
    'age' => 'integer|min:0|max:150'
);
```

$guardedというプロパティは、入力のガードを設定している。

続いて/views/person/のフォルダ内にadd.blade.phpという名前でファイルを作成する。

```php5:add.blade.php
@extends('layouts.helloapp')

@section('title', 'Person.Add')

@section('menubar')
    @parent
    新規作成ページ
@endsection

@section('content')
    @if (count($errors) > 0)
    <div>
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
    @endif
    <table>
        <form action="/person/add" method="post">
            {{ csrf_field() }}
            <tr><th>name: </th><td><input type="text" name="name" value="{{old('name')}}"></td></tr>
            <tr><th>mail: </th><td><input type="text" name="mail" value="{{old('mail')}}"></td></tr>
            <tr><th>age: </th><td><input type="number" name="age" value="{{old('age')}}"></td></tr>
            <tr><th></th><td><input type="submit" value="send"></td></tr>
        </form>
    </table>
@endsection

@section('footer')
copyight 2018 tanaka
@endsection
```

@if (count($errors) > 0)で、エラーがある場合のみ処理を実行する様にしている。

```php5:抜粋
@foreach ($errors->all() as $error)
    <li>{{ $error }}</li>
@endforeach
```

上記の表記をエラーメッセージを全て表示させている。

/person/addのアクションをコントローラに作成する。
PersonController.phpに以下を追記する。

```php5:PersonController.php
public function add(Request $request)
{
    return view('add');
}

public function create(Request $request)
{
    $this->validate($request, Person::$rules);
    $person = new Person;
    $form = $request->all();
    unset($form['_token']);
    $person->fill($form)->save();
    return redirect('/person');
}
```

_tokenという値は、CSRF用非表示フィールドとして用意されている。

web.phpにルート情報を追記する。

```php5:web.php
Route::get('person/add', 'PersonController@add');
Route::post('person/add', 'PersonController@create');
```

person/addにアクセスしてフォームを入力し、保存できるのを確認できればOK!

<img width="1440" alt="スクリーンショット 2018-10-20 11.15.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/6151fce4-a536-0f6b-1f2f-b34f8ff144b4.png">

<img width="1440" alt="スクリーンショット 2018-10-20 11.16.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/404e3fad-fe27-d31e-4e13-19f9b018c048.png">

ちなみに追加されている「レコード追加」のリンク先は/person/addに直接ページへ行ける様にした。

```php5:index.blade.php
@section('content')
    <table>
        <tr><th>Data</th></tr>
        @foreach ($items as $item)
            <tr>
                <td>{{$item->getData()}}</td>
            </tr>
        @endforeach
    </table>
    
    //追加箇所
    <tr>
        <td>
            <a href="./person/add">レコード追加</a>    
        </td>
    </tr>
    
@endsection
```
## 値を更新できる様にする。
/views/person内に「edit.blade.php」というフォルダを作成する。

```php5:edit.blade.php
@extends('layouts.helloapp')

@section('title', 'Person.Edit')

@section('menubar')
    @parent
    編集ページ
@endsection

@section('content')
    @if (count($errors) > 0)
    <div>
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error}}</li>
            @endforeach
        </ul>
    </div>
    @endif
    <table>
        <form action="/person/edit" method="post">
            {{ csrf_field() }}
            <input type="hidden" name="id" value="{{$form->id}}">
            <tr><th>name: </th><td><input type="text" name="name" id="{{$form->name}}"></td></tr>
            <tr><th>mail: </th><td><input type="text" name="mail" id="{{$form->mail}}"></td></tr>
            <tr><th>age: </th><td><input type="number" name="age" id="{{$form->age}}"></td></tr>
            <tr><th></th><td><input type="submit" value="send"></td></tr>
        </form>
    </table>
@endsection

@section('footer')
copyrught 2018 tanaka
@endsectionß
```

/person/editのアクションをPersonController.phpに追記する。

```php5:PersonController.php
public function edit(Request $request)
{
    $person = Person::find($request->id);
    return view('person.edit', ['form' => $person]);
}

public function update(Request $request)
{
    $this->validate($request, Person::$rules);
    $person = Person::find($request->id);
    $form = $request->all();
    unset($form['_token']);
    $person->fill($form)->save();
    return redirect('/person');
}
```

web.phpにルート情報を追記する。

```php5:web.php
Route::get('person/edit', 'PersonController@edit');
Route::post('person/edit', 'PersonController@update');
```

上記追記修正して、/person/edit?id=3のようにアクセスし、更新できればOK。

<img width="1440" alt="スクリーンショット 2018-10-20 19.16.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/db769151-3d60-68ec-421a-99d4fbb9baac.png">

<img width="1440" alt="スクリーンショット 2018-10-20 19.21.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/397eacdd-114f-4303-a695-01d09d16f8cb.png">

## レコードを削除する

/views/person内にdel.blade.phpという名前のファイルを作成する。

```php5:del.blade.php
@extends('layouts.helloapp');

@section('title', ,'Person.Delete')

@section('menubar')
    @parent
    削除ページ
@endsection

@section('content')
    <table>
        <form action="/person/del" method="post">
            {{ csrf_field() }}
            <input type="hidden" name="id" value="{{$form->id}}">
            <tr><th>name: </th><td>{{$form->name}}</td></tr>
            <tr><th>mail: </th><td>{{$form->mail}}</td></tr>
            <tr><th>age: </th><td>{{$form->age}}</td></tr>
            <tr><th></th><td><input type="submit" value="send"></td></tr>
        </form>
    </table>
@endsection

@section('footer')
copyright 2018 tanaka.
@endsection
```

delete　とremoveメソッドをPersonController.phpに追記する。

```php5:PersonController.php
public function delete(Request $request)<img width="1440" alt="スクリーンショット 2018-10-20 19.45.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/dd97871a-5eb6-e87d-cfb9-f28a0e282a1c.png">

{
    $person = Person::find($request->id);
    return view('person.del', ['form' => $person]);
}

public function remove(Request $request)
{
    Person::find($request->id)->delete();
    return redirect('/person');
}
```

web.phpにルート情報を追記する。

```php5:web.php
Route::get('person/del', 'PersonController@delete');
Route::post('person/del', 'PersonController@remove');
```

/person/del?id=3のようにアクセスし、レコードを削除できればOK!

<img width="1440" alt="スクリーンショット 2018-10-20 19.45.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/0495a57c-9db8-e638-bca7-89d871d7eaa7.png">

<img width="1440" alt="スクリーンショット 2018-10-20 19.45.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/48702ac3-21e6-28f2-733b-ac1286804c04.png">

これでモデルを使ったCRUDは一通りできた！

下記は番外編なので読み飛ばしてしまって問題なし。

## Herokuに作成したアプリケーションをデプロイして動かしてみる。
勉強のため今作成したアプリケーションをHerokuに上げてみる。

GitHubへ連携しているためGitHubにpushすれば自動でHerokuにもpushされる設定にしているため、
Herokuにファイルをアップする部分は割愛する。

Heroku内でマイグレーションを実行する。

```bash:command
heroku run php artisan migrate
**************************************
*     Application In Production!     *
**************************************

 Do you really wish to run this command? (yes/no) [no]:
 > yes

Migrating: 2018_10_15_130105_create_people_table
Migrated:  2018_10_15_130105_create_people_table
```

テーブルの作成をしたので実際サイトに移動できるか試してみる。

余談だがgitignoreには充分気をつけるようにする。
viewファイルがgithubにコミットされていなくて何事かと思って小一時間調査したらgitignoreのファイルの中に「/resources」と記載がありそれが原因でコミットされていなかった。

herokuから/personにログインしてみると

<img width="1440" alt="スクリーンショット 2018-10-21 11.06.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/544be7e1-53aa-5157-92cb-4d3678fd780c.png">

上記のようなエラーが。。。色々と調べてようやく原因がわかった。

heroku内のpersonディレクトリは、

```bash:command
~/resources/views $ ls -ltr
total 16
-rw------- 1 u52455 dyno 2798 Oct 20 14:36 welcome.blade.php
drwx------ 2 u52455 dyno 4096 Oct 20 14:36 layouts
drwx------ 2 u52455 dyno 4096 Oct 20 14:36 board
drwx------ 2 u52455 dyno 4096 Oct 20 14:36 Person
~/resources/views $
```

「P」ersonになっているが、PersonController.phpの方は、

```php5:PersonController.php
return view('person.index', ['items' => $items]);
```

「p」ersonになっていたためperson.indexがないとうエラーが発生していた。
PersonController.phpの記述を下記のように変更して再度アクセスすると、

```php5:PersonController.php
return view('Person.index', ['items' => $items]);
```

<img width="1440" alt="スクリーンショット 2018-10-21 11.26.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/b835ed09-4f8c-8767-73c7-b1e526918ddc.png">

上図のようにアクセスできるようになった。（ちなみに/person/addにもアクセスできDBにレコードも追加できた。）

一通りCRUD機能を試して問題なかったのでOK。
これでHerokuにCRUD機能を一通りアップできた。