Laravel - form でデータの新規追加・編集・DB操作

####新規作成、編集と不正対策
#####参考サイト
[初めてのLARAVEL 5.6 : (23) FLASH メッセージ](https://laravel10.wordpress.com/2015/03/17/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AElaravel-5-23-flash-%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8/)
[Laravel 5.7 Eloquent：利用の開始](https://readouble.com/laravel/5.7/ja/eloquent.html)
[Laravel 5.8 コレクション](https://readouble.com/laravel/5.8/ja/collections.html)
[Laravel】DBにデータを保存する方法。createとinsertの違いなど](https://qiita.com/katsunory/items/87a73297f44a65f1474f)

#####ルーティング

```php:web.php
<?php
//共用get
Route::get('/item/edit', 'ItemController@edit')->name('item.edit');
//新規作成
Route::post('/item/create', 'ItemController@create')->name('item.create');
//編集
Route::get('/item/detail/{id}', 'ItemController@detail')->name('item.detail');
Route::post('/item/edit', 'ItemController@edit')->name('item.edit');
```

共用getの ItemController@editは post用に作られていて、Requestを引数に取るが、上の様にgetでアクセスすれば引数なしで処理される。

######モデルの準備
モデルではDB利用のための準備をします。

```php:app/Item/php
<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Item extends Model
{
    protected $fillable = ['name', 'content', 'price', 'quantity'];
    protected $table = 'items';
}                                                                                                                                     
```

#####コントローラー
```php:ItemController
use Illuminate\Http\Request;
use App\Http\Requests\ItemRequest;
use App\Item;

class ItemController extends Controller
{
    public function index() {
        $items = Item::all();
        return view('item.index', compact('items'));
    }
    public function detail($id) {
        $item = Item::find($id);
        return view('item.detail', compact('item'));
    }
    public function edit(Request $request) {
        $name = $request->input('name');
        $content = $request->input('content');
        $price = $request->input('price');
        $quantity = $request->input('quantity');
        return view('item.edit', compact('name', 'content', 'price', 'quantity'));
    }
    //ItemRequestは下記のformRequestでバリデーションを参照。
    public function create(ItemRequest $request) {
        $name = $request->input('name');
        $content = $request->input('content');
        $price = $request->input('price');
        $quantity = $request->input('quantity');
        Item::create(compact('name', 'content', 'price', 'quantity'));
        set_message('商品を追加しました。');
        return redirect(route('item.index'));
    }
    public function update(ItemRequest $request) {
        $item = Item::findOrFail($id);
        $item->fill(['name' => $request->input('name')]);
        $item->fill(['content' => $request->input('content')]);
        $item->fill(['quantity' => $request->input('quantity')]);
        $item->save();
        set_message('内容を修正しました。');
        return redirect(route('item.detail', ['id' => $id]));
    }
}
```
参考
[formRequestでバリデーション](https://qiita.com/Fell/items/14d637a93c5134ff126f)

自作ヘルパ関数のset_message()に関しては下記を参照してください。
[ヘルパ関数の自作 by Laravel](https://qiita.com/Fell/items/8e01db9aa8c3b0cf0cf9)

#####編集ビュー

```php:edit.blade.php
@section('content')
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
    <?php
    $name = old('name');
    $content = old('content');
    $price = old('price');
    $quantity = old('quantity');
    ?>
@endif
<?php $is_create = (session('id') == ''); ?>
@if ($is_create)
    <?php $address = 'item.create'; ?>
    <h1>{{ '新規登録' }}</h1>
@else
    <?php $address = 'item.update'; ?>
    <h1>{{ '商品編集' }}</h1>
@endisset
<body>
    <form method="post" action="{{ route($address) }}">
        {{ csrf_field() }}
        <div><label>商品名:</label> <input type="text" name="name" value="{{ $name }}"></div>
        <div><label>説明:</label> <textarea name="content">{{ $content }}</textarea></div>
        @if ($is_create)
            <div><label>値段:</label> <input type"text" name="price" value="{{ $price }}"></div>
        @else
            <div><input type="hidden" name="price" value="{{ $price }}"></div>
        @endif
        <div><label>在庫:</label> <input type="text" name="quantity" value="{{ $quantity }}"></div>
        <div><button type="submit">登録</button></div>
    </form>
    <h2><a href="{{ route('item.index') }}">商品一覧へ戻る</a></h2>
</body>
@endsection
```

######LaravelのDB操作にはeloquentという仕組みが用意されています。
ここではあまり詳しく触れませんが下記のような呼び出しがeloquentメソッドになります。

```php
Item::get();
Item::find($id);
```

######eloquantの返す型は Model: 単数形 か colection(Model): 複数形

[【Laravel】DB登録値取得時のfind()、get()、first()の返り値早見表](https://qiita.com/sola-msr/items/fac931c72e1c46ae5f0f)

laravelのcollectionを理解せずにeloquantだけ調べてデータを眺めても？？だと思う。
collectionを理解できると公式のeloquantが読める。

上の参考サイトのキモは、データが戻り値が単数・複数をきちんと把握すること。

find -> 単数 -> Model
where->get() -> 複数 -> Collection(Model)
where->first() -> 単数 -> Model

findやfirstは性格上データを見つけ次第DBの検索をやめるはずだから積極的に使いたい。(速いし低負荷）
######不正対策
getパラメータ、hiddenは丸見えです。
改ざんされると思って使うぐらいがいいね。

＊注意
ここでの不正対策はAuthをわざと使ってません。
あまりいい例ではないです。
laravel認証を使えばAuth::idを使ってもっと簡単に不正対策できます。
ぜひ調べて見てください。
#####最後に

今回は理解のしやすさを優先してDBアクセスをコントローラーにいれて書きました。
下記のリンクにはMVCを意識した書き方を載せています。
さらなるレベルアップに生かして下さい！
[MVCでカート機能１ - Model編 for Laravel](https://qiita.com/Fell/items/1c4c2fe145cad0a6a0d7)
[MVCでカート機能２ - View編 for Laravel](https://qiita.com/Fell/items/2c7cc5927e88536c434f)
[MVCでカート機能３ - Controller編 for Laravel](https://qiita.com/Fell/items/bc7d7acec68c682969f0)

LGTMよろしくお願いします。
モチベーションが上がります！