PHP Laravel 6 おすすめ映画投稿サイト作成過程 6:削除機能作成編


ルーティング

destroyを使用します。

| DELETE    | recommends/{recommend}      | recommends.destroy | App\Http\Controllers\RecommendController@destroy                       | web          |

コントローラー

Modelのデリートメソッドを使用します。
editなどとは違い、デリート用のページを用意する必要はないためindexへリダイレクトさせます。

recommend/app/Http/Controllers/RecommendController.php
public function destroy(Recommend $recommend)
    {
        $recommend->delete();
        return redirect()->route('recommends.index');
    }

indexからdestroyへ削除したいデータを送る

destroyは、POSTやPUTと同様にformタグで送る必要があることに注意してください。
今回は、削除時に確認メッセージを表示させるようにしました。

recommend/resources/views/recommends/index.blade.php
<table>
 <thead>
   <tr>
     <th>タイトル</th>
     <th>画像:現在は空</th>
     <th>URL</th>
     <th>操作</th>
   </tr>
 </thead>
 @foreach($recommends as $recommend)
   <tr>
     <td>{{$recommend->title}}</td>
     <td>{{$recommend->image_file_name}}</td>
     <td>{{$recommend->url}}</td>
     <td><a href="{{route('recommends.show', $recommend->id)}}">詳細</a></td>
     <td><a href="{{route('recommends.edit', ['recommend' => $recommend])}}">編集</a></td>
     <td>
      <form method='POST'action="{{route('recommends.destroy', ['recommend' => $recommend])}}">
     @csrf
     @method('DELETE')
     <button onclick="return confirm('本当に削除しますか?')" action="submit">削除</button>
     </td>
  @endforeach
 </table>

フラッシュメッセージの追加

いくつかの方法があるようですが、今回は一番簡単そうなチェーンメソッドでwithを追加

recommend/app/Http/Controllers/RecommendController.php
public function destroy(Recommend $recommend)
    {
        $recommend->delete();
        return redirect()->route('recommends.index')->with('status', '削除しました');
    }

次に、フラッシュを表示させるviewを作成していきます。

投稿・編集・削除時に表示させたいので、専用のviewファイルを作成し、表示させたいviewファイルにincludeさせます。
今回は、_additonalディレクトリ内にalart.blade.phpというviewファイルを作成しました。

viewファイルの内容については、if文でstatusの有無を判断し、アラートを表示させるようにします。

statusの有無を判断する方法は、sessionメソッドを使用しました。

recommend/resources/views/_additional/alart.blade.php
@if(session()->has('status'))
<div>{{session('status')}}</div>
@endif

上記をviewにincludeさせます

recommend/resources/views/recommends/index.blade.php
<div class="card-body">
    <table>
    @include('_additional.alart')
        <thead>
            <tr>
                <th>タイトル</th>
                <th>画像:現在は空</th>
                <th>URL</th>
                <th>操作</th>
            </tr>
        </thead>
        @foreach($recommends as $recommend)
        <tr>
            <td>{{$recommend->title}}</td>

            <td>{{$recommend->image_file_name}}</td>
            <td>{{$recommend->url}}</td>
            <td><a href="{{route('recommends.show', $recommend->id)}}">詳細</a></td>
            <td><a href="{{route('recommends.edit', ['recommend' => $recommend])}}">編集</a></td>
            <td>
                <form method='POST' action="{{route('recommends.destroy', ['recommend' => $recommend])}}">
                    @csrf
                    @method('DELETE')
                    <button onclick="return confirm('本当に削除しますか?')" action="submit">削除</button>
            </td>
            </form>
        </tr>
        @endforeach
    </table>
</div>

新規投稿と編集にもフラッシュメッセージを表示させる

updateとcreateに同じ処理をします。

recommend/app/Http/Controllers/RecommendController.php
public function update(Request $request, Recommend $recommend)
    {
        $recommend->update($request->all());
        return redirect()->route('recommends.show', compact('recommend'))->with('status', '編集しました');
    }
recommend/app/Http/Controllers/RecommendController.php
public function store(Request $request)
    {
        Recommend::create($request->all());
        return redirect()->route('recommends.index')->with('status', '投稿しました');
    }
recommend/resources/views/recommends/show.blade.php
<div class="card">
    <div class="card-header">{{ __('Login') }}</div>
    @include('_additional.alart')
    <div class="card-body">
        <table>
            <tr>
                <th>タイトル</th>
                <td>{{$recommend->title}}</td>
            </tr>
            <tr>
                <th>画像</th>
                <td>{{$recommend->image_file_name}}</td>
            </tr>
            <tr>
                <th>URL</th>
                <td>{{$recommend->url}}</td>
            </tr>
            <tr>
                <th>概要</th>
                <td>{{$recommend->description}}</td>
            </tr>
            <tr>
                <th>感想</th>
                <td>{{$recommend->Impressions}}</td>
            </tr>
        </table>
    </div>
</div>

バリデーション

現在のフォームでは、nulableで空欄を許可しているもの以外を空欄で登録しようとするとエラー画面に飛ばされてしまいます。
それを防ぐため、バリデーションを設定して入力項目に制限を加えます。

recommend/database/migrations/2020_09_23_105017_create_recommends_table.php
public function up()
    {
        Schema::create('recommends', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title');
            $table->string('image_file_name', 100)->nullable();
            $table->string('image_title',100)->nullable();
            $table->string('url');
            $table->string('description')->nullable();
            $table->string('Impressions')->nullable();
            $table->timestamps();
        });
    }
バリデーション の設定手順

フォームリクエスト作成

$ php artisan make:request RecommendPostRequest

リクエストに適用するバリデーション ルールを設定

recommend/app/Http/Requests/RecommendPostRequest.php
class recommendPostRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' => 'required|max:20',
            'url' => 'required',
            'description' => 'max:200',
            'Impressions' => 'max:200',
        ];
    }
}

バリデーションルールをコントローラーメソッドのタイプヒントに指定

recommend/app/Http/Controllers/RecommendController.php
use App\Http\Requests\RecommendPostRequest;
recommend/app/Http/Controllers/RecommendController.php
 public function store(RecommendPostRequest $request)
    {
        Recommend::create($request->all());
        return redirect()->route('recommends.index')->with('status', '投稿しました');
    }
recommend/app/Http/Controllers/RecommendController.php
public function update(RecommendPostRequest $request, Recommend $recommend)
    {
        $recommend->update($request->all());
        return redirect()->route('recommends.show', compact('recommend'))->with('status', '編集しました');
    }

エラーメッセージの表示

バリデーション反した場合、自動的にエラーメッセージを生成してくれます。
それを設定するため、以下のように記述しました。

recommend/resources/views/recommends/edit.blade.php
<tr>
    <th><input type="text" name='title' value="{{$recommend->title ?? ''}}"></th>
      @error('title')
      <span class="invalid-feedback" role="alert">
          <strong>{{ $message }}</strong>
      </span>
      @enderror
    <th><input type="URL" name='url' value="{{$recommend->url ?? ''}}"></th>
      @error('url')
      <span class="invalid-feedback" role="alert">
          <strong>{{ $message }}</strong>
      </span>
      @enderror
    <th><textarea name="description" id="" cols="30" rows="10">{{$recomend->description ?? ''}}</textarea></th>
    <th><textarea name="Impressions" id="" cols="30" rows="10">{{$recomend->Impressions ?? ''}}</textarea></th>
</tr>