LaravelのEditとDelete

こんにちはscouterでフロントエンジニアをしているhirokinishizawaです! laravel勉強ブログもVersion4.0.0になりました!

前回投稿した記事 techblog.scouter.co.jp

前回は釣りの記録を作成する際にデータベースにレコードを追加できるようにしました。なので今回は編集と削除を出来るようにしました!

はじめに

作成したものの動き

トップページの各記録に編集する削除するを追加しました

gyazo.com

あとレイアウトとして追加したのが

編集ページと

gyazo.com

削除する時の確認ページです

gyazo.com

やったこと

1.記録を編集できるようにした

2.Requestファイルを使って作成時と編集時のvalidateを一つにまとめた

3.記録を削除できるようにした

記録を編集

web.php

<?php

Route::get('/posts/{post}/edit', 'PostsController@edit');
Route::patch('/posts/{post}', 'PostsController@update');

PostsController.php

<?php

  public function edit(Post $post)
    {
        return view('posts.edit')->with('post', $post);
    }

 public function update(PostRequest $request, Post $post)
    {
        $this->validate($request, [
            'fish_name' => 'required',
            'year' => 'required|integer|between:1990,2018',
            'month' => 'required|integer|between:1,12',
            'day' => 'required|integer|between:1,31',
            'prefecture' => 'required',
            'place' => 'required'
        ]);
        $post->fish_name = $request->fish_name;
        $post->year = $request->year;
        $post->month = $request->month;
        $post->day = $request->day;
        $post->prefecture = $request->prefecture;
        $post->place = $request->place;
        $post->save();
        return redirect('/');
    }

前回の@postのときとほぼ同じです。違うのは引数でpostを受け取るので$post = new Post();このように新しくPostを作らなくていいところです。

edit.blade.php作成

コード自体は作成ページと編集ページのレイアウト見てもらうとわかると思いますがほぼかわっていません。変わったのはpostではくupdateするためにメソッドにpatchをを使用しました。

編集ページ

@section('content')
    <h1>記録編集ページ<a href="{{ url('/') }}" class="header-menu">戻る</a></h1>

    <form method="post" action="{{ url('/posts', $post->id) }}">
        {{ csrf_field() }}
        {{ method_field('patch') }}
        <div class="flex-box">
            <div class="column">
                魚の名前
            </div>
            <div>
                <input type="text" name="fish_name" placeholder="ブラックバス" value="{{old('fish_name', $post->fish_name)}}">
                @if($errors->has('fish_name'))
                    <span class="error">{{ $errors->first('fish_name') }}</span>
                @endif
            </div>
        </div>...

新規作成ページ

@section('content')
    <h1>記録を作成する<a href="{{ url('/') }}" class="header-menu">戻る</a></h1>

    <form method="post" action="{{ url('/posts') }}">
        {{ csrf_field() }}
        <div class="flex-box">
            <div class="column">
                魚の名前
            </div>
            <div>
                <input type="text" name="fish_name" placeholder="ブラックバス" value="{{old('fish_name')}}">
                @if($errors->has('fish_name'))
                    <span class="error">{{ $errors->first('fish_name') }}</span>
                @endif
            </div>
        </div>...

見比べると編集ページの方には{{ method_field('patch')}}がありますね。これをformタグの中に書くことによりhttpメソッドのpatchが使えるようになって{{ url('/posts') }}にidを渡すことにより上書きできるようになります。

(後で出てくるdeleteでも似たようなことをしています)

Requestファイル使用

前回postする際に書いたvalidateですがeditでも同じ条件でvalidateを掛けたいのですが下のように重複するのはあまり好ましくないのでRequestファイルに共通部分を書きました。

<?php

public function post(PostRequest $request)
    {
        $this->validate($request, [
            'fish_name' => 'required',
            'year' => 'required|integer|between:1990,2018',
            'month' => 'required|integer|between:1,12',
            'day' => 'required|integer|between:1,31',
            'prefecture' => 'required',
            'place' => 'required'
        ]);
        
        $post = new Post();
        $post->fish_name = $request->fish_name;
        $post->year = $request->year;
        $post->month = $request->month;
        $post->day = $request->day;
        $post->prefecture = $request->prefecture;
        $post->place = $request->place;
        $post->save();
        return redirect('/');
    }

    public function update(PostRequest $request, Post $post)
    {
        $this->validate($request, [
            'fish_name' => 'required',
            'year' => 'required|integer|between:1990,2018',
            'month' => 'required|integer|between:1,12',
            'day' => 'required|integer|between:1,31',
            'prefecture' => 'required',
            'place' => 'required'
        ]);
        
        $post->fish_name = $request->fish_name;
        $post->year = $request->year;
        $post->month = $request->month;
        $post->day = $request->day;
        $post->prefecture = $request->prefecture;
        $post->place = $request->place;
        $post->save();
        return redirect('/');
    }
php artisan make:request PostRequest

こちらのコマンドでApp\Http\Requestsの下にRequestファイルを作成することが出来ます。

<?php
    public function rules()
    {
        return [
            'fish_name' => 'required',
            'year' => 'required|integer|between:1990,2018',
            'month' => 'required|integer|between:1,12',
            'day' => 'required|integer|between:1,31',
            'prefecture' => 'required',
            'place' => 'required'
        ];
    }

    public function messages()
    {
        return [
            'fish_name.required' => '魚の名前を入れてください',
            'year.required' => '1990年から2018年の間で記入してください',
            'month.required' => '1年の中で1月から12月までしかありませんよ',
            'day.required' => '1ヶ月の中で1日から31日までしかありませんよ。',
            'prefecture.required' => '情報提供してください',
            'place.required' => '情報提供してください',
        ];
    }

rules()は名前の通りルールを書いていきます。

下のmessages()はそのルールを破った時にでてくる文章を作ることが出来ます!

前回は文字の変更のやり方が分からなかったのでとても分かりやすく便利だなと思ったRequestファイルでした!

記録を削除

web.php

<?php
Route::get('/posts/delete', 'PostsController@delete')->name('post.delete');
Route::delete('/posts/remove', 'PostsController@remove')->name('post.remove');

削除の方ではnameを使ってみました。nameについては後で説明します。

PostsController.php

<?php

    public function delete(Request $request)
    {
        $post = Post::find($request->id);
       return view('posts.delete')->with('post',$post);
    }

    public function remove(Request $request)
    {
        $post = Post::find($request->id);
        $post->delete();
        return redirect('/');
    }

delete.blade.php作成

コードはこのようになっています

@extends('layouts.app')

@section('content')
    <h1>本当に削除しますか?<a href="{{ url('/') }}" class="header-menu">戻る</a></h1>

    <div class="fishing-record">
        <div class="flex-box">
            <div class="column">魚種</div>
            <div class="text">{{ $post->fish_name }}</div>
        </div>
        <div class="flex-box">
            <div class="column">釣った日付</div>
            <div class="text">{{ $post->year }}年{{ $post->month }}月{{ $post->day }}日</div>
        </div>
        <div class="flex-box">
            <div class="column">釣った場所</div>
            <div class="text">{{ $post->prefecture }}: {{ $post->place }}</div>
        </div>
    </div>
    <form action='{{ route('post.remove') }}' method='post'>
        {{ csrf_field() }}
        {{ method_field('delete') }}
        <input type='hidden' name='id' value='{{ $post->id }}'><br>
        <input type='submit' value='削除'>
    </form>
@endsection
  • {{ route('post.remove') }} 先程のweb.phpで使用したnameはこのようにrouteとして使用することが出来ます

  • {{ method_field('delete') }} 編集機能のpatchと同じです。httpメソッドを使用できるようにしています。

躓いた点

今回editやdeleteをするのにid毎にそれぞれページ遷移させるのでidを渡さなければいけませんでした。以前作成ページを作った時は作成するボタン(遷移ボタン)を押したら作成ページに飛ぶだけでルーティングはRoute::get('/posts/create'だったので遷移ボタンのコードを書く時はhref="{{ url('/posts/create') }}"とこのような書き方をしました。ですが今回idを渡すのでルーティングはRoute::get('/posts/{post}/edit'。遷移先のコードはhref="{{ url('/posts/edit', $post->id) }}"とかいたのですが、遷移した先は/posts/edit/1になってしまいページがないよと言われました。なので別のページ遷移のやり方を調べhref="{{ action('PostsController@edit', $post) }}"という書き方で無事'/posts/1/edit'となりidごとのeditページやdeleteページに遷移することができました! href="{{ action('PostsController@edit', $post) }}"と同様にhref="{{route('post.edit', $post) }}"とnameを決めてrouteで書いても出来ました!というよりこっちの方が一般的みたいです!

終わりに

前回のデータベースを使って記録の更新に続きちょっとだけ応用したeditとdeleteですが今回調べるにあたりいろいろな人のブログを見たら大体一緒にやってることが多かったので次回は脱初心者に向けてなにかいいネタないか考えたいと思います(勉強するにあたって何をすればいいかわからないのでネタ提供求めますww)

来週もよろしくおねがいしますー!