22
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2019-11-22

####新規作成、編集と不正対策
#####参考サイト
初めてのLARAVEL 5.6 : (23) FLASH メッセージ
Laravel 5.7 Eloquent:利用の開始
Laravel 5.8 コレクション
Laravel】DBにデータを保存する方法。createとinsertの違いなど

#####ルーティング

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利用のための準備をします。

app/Item/php
<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

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

#####コントローラー

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でバリデーション

自作ヘルパ関数のset_message()に関しては下記を参照してください。
ヘルパ関数の自作 by Laravel

#####編集ビュー

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メソッドになります。

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

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

【Laravel】DB登録値取得時のfind()、get()、first()の返り値早見表

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でカート機能1 - Model編 for Laravel
MVCでカート機能2 - View編 for Laravel
MVCでカート機能3 - Controller編 for Laravel

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

22
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?