Laravel初心者向けの無料チュートリアル④つぶやきの編集と削除

Laravel初心者向けの無料チュートリアル④つぶやきの編集と削除

1270 回閲覧されました

みなさんこんにちは、jonioです。

今回が最後の解説になります。

今回はつぶやきを編集して更新するのとつぶやきを削除する解説です。

1回目の解説から読んで欲しいのですが読んでない方は↓からどうぞ。

まずはつぶやきを編集して更新する処理です。

 

つぶやきを編集して更新する処理

つぶやきを編集して更新する時ですが下記が必要になります。

  • つぶやきを編集するページの表示
  • つぶやきを編集できる様にする為の処理
  • つぶやきを更新する処理

まずはつぶやきを更新するページを表示するための処理をします。

リソースコントローラーを使っていてルーティングは必要ないのでコントローラーからです。

 

つぶやきを更新するページを表示するコントローラー

↓の7つのアクションの内どれに当たるか分かりますか?

  • index : つぶやき一覧の表示
  • create : つぶやきの作成
  • show : 複数あるつぶやきの内の1つの表示
  • store : 作成したつぶやきの保存
  • update : つぶやきを編集した時の更新
  • edit : つぶやきの内容の編集
  • destroy : つぶやきの削除

下から2つ目のeditアクションですよね。

だからPostコントローラーのeditアクションに記述をします。

この時のビューはedit.blade.phpですが「php artisan route:list」をして↓から分かります。

PostController.phpのコードを↓にします。

/**
* Show the form for editing the specified resource.
*
* @param  int  $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
  return view('post.edit');                             //この行を修正
}

次はビューを作成します。

 

つぶやきを更新するページ

postフォルダの下にedit.blade.phpを作成します。

つぶやきを更新するページですがつぶやきを作成するページに似ている方がやりやすいですよね(↓がつぶやきを作成するページ)

↑のファイルはcreate.blade.phpです。

中身をコピーしてedit.blade.phpに貼ります。

貼った状態が↓です。

@extends('layouts.app')
@section('content')
<div class="row">
    <div class="col-md-10 mt-6  ms-auto me-auto">
        <div class="card-body">
            <h1 class="mt4">つぶやきの作成</h1>
            <form method="post" action="{{route('post.store')}}">
                @csrf
                <div class="form-group mt-3">
                        <label for="body">つぶやきの内容</label>
                        <textarea name="body" class="form-control" id="body" cols="30" rows="10" placeholder="ここにつぶやきの内容を書く"></textarea>
                </div>
                <button type="submit" class="btn btn-success mt-3">つぶやく</button>
            </form>
        </div>
    </div>
 </div>
 @endsection

今はつぶやきの内容を編集するページなので少し変えます。

@extends('layouts.app')
@section('content')
<div class="row">
    <div class="col-md-10 mt-6  ms-auto me-auto">
        <div class="card-body">
            <h1 class="mt4">つぶやきの編集</h1>
            <form method="post" action="{{route('post.store')}}">
                @csrf
                <div class="form-group mt-3">
                        <label for="body">つぶやきの内容</label>
                        <textarea name="body" class="form-control" id="body" cols="30" rows="10" placeholder="ここにつぶやきの内容を書く"></textarea>
                </div>
                <button type="submit" class="btn btn-success mt-3">つぶやく</button>
            </form>
        </div>
    </div>
 </div>
 @endsection

これで「http://localhost:8888/post/1/edit」にアクセスすると↓になります。

1」が分からないと思いますが後で説明するので今はとりあえずURLにアクセスして下さい。

 これでつぶやきを編集するページを表示する事ができたので次はつぶやきを更新する処理です。

 

つぶやきを編集できる様にするコントローラー

つぶやきを編集する時ですがつぶやき一覧が表示されているページ(index.blade.php)に編集ボタンがあった方がアプリが使いやすいですよね?

だからindex.blade.phpに記述を追加します。

@extends('layouts.app')
@section('content')
@foreach ($posts as $post)
<div class="container-fluid mt-20" style="margin-left:-10px;">
    <div class="row">
        <div class="col-md-12 w-75 ms-auto me-auto">
            <div class="card mb-2">                         //mb-2を修正
                <p>{{$post->body}}</p>
            </div>
            <a href=""><button class="btn btn-primary mb-4">編集</button></a>            //この行を追加
        </div>
    </div>
</div>
@endforeach
@endsection

これで「http://localhost:8888/post」にアクセスすると↓の表示になります。

それではコントローラーの記述をしますが青色の背景色の編集ボタンをクリックした時にPostコントローラーにつぶやきの情報を渡してつぶやきの編集ページに反映させますがそれができるようにするためにindex.blade.phpを少し修正します。

@extends('layouts.app')
@section('content')
@foreach ($posts as $post)
<div class="container-fluid mt-20" style="margin-left:-10px;">
    <div class="row">
        <div class="col-md-12 w-75 ms-auto me-auto">
            <div class="card mb-2">
                <p>{{$post->body}}</p>
            </div>
            <a href="{{route('post.edit',$post)}}"><button class="btn btn-primary mb-4">編集</button></a>       //この行を修正
        </div>
    </div>
</div>
@endforeach
@endsection

10行目に「{{route(post.edit,$post)}}」を追加しています。

post.editは何度も登場しているphp artisan route:listで分かります。

コントローラーからビューに情報を渡す事ができますがビューからコントローラーにも情報を渡す事ができてそれが$postです。

$postはindex.blade.phpの中の記述の「@foreach($posts as $post)」の$postと同じです。

$postでビュー(index.blade.php)からPostコントローラーに情報が渡されてそこから編集するページ(edit.blade.php)に情報を渡します。

先ほど編集するページである「http://localhost:8888/post/1/edit」にアクセスしたのを覚えていますでしょうか?

この1に当たるのが$postです。

1はカラムのidの番号なのですがphpMyAdminで確認できます。

つぶやきの1つ1つにid番号が振られています。

それではPostコントローラーのeditアクションで$postを受け取る事ができるようにします。

//ここから修正
public function edit(Post $post)
{
  return view('post.edit',compact('post'));
}
//ここまで修正

2行目の「edit(Post $post)」の$postはindex.blade.phpの「{{route(post.edit’,$post)}}」の$postと同じです。

Post $post」でPostモデルの情報を$postで使う事ができるという意味です。

これでindex.blade.phpに表示されるつぶやきの下にある編集ボタンをクリックするとそれぞれのつぶやきに対して編集画面に移動します。

今の状態ではどのつぶやきの編集画面も同じ表示になります。

後でどのつぶやきを編集しようとしているかが分かる様にしますが今はとりあえずURLが違う事で他のつぶやきの編集画面に入っている事を確認して下さい。(↓の2がつぶやきによって変わるはずです)

それではどのつぶやきを編集しているかが分かる様にします。

つぶやきを編集するビューのedit.blade.phpを修正します。

@extends('layouts.app')
@section('content')
<div class="row">
    <div class="col-md-10 mt-6  ms-auto me-auto">
        <div class="card-body">
            <h1 class="mt4">つぶやきの編集</h1>
            <form method="post" action="{{route('post.update',$post)}}">             //この行を修正
                @csrf
                @method('put')                                                                                                                //この行を追加
                <div class="form-group mt-3">
                        <label for="body">つぶやきの内容</label>
                        <textarea name="body" class="form-control" id="body" cols="30" rows="10" placeholder="ここにつぶやきの内容を書く">{{$post->body}}</textarea>           //この行を修正
                </div>
                <button type="submit" class="btn btn-success mt-3">つぶやく</button>
            </form>
        </div>
    </div>
 </div>
 @endsection

7行目の「post.update」ですがつぶやきを更新するからこれになります。

9行目ですが更新内容を保存する時は8行目の「@csrf」の下に「@method(‘put’)」を付けるのを知っておきましょう。

12行目ですが「{{$post->body}}」の$postですがPostコントローラーのeditアクションから渡された情報です。

「->body」がデータベースのbodyカラムの値(つぶやき)になります。

だから「$post->body」で該当するつぶやきの内容になります。

これでつぶやき一覧のページ(index.blade.php)でどれでもいいので編集ボタンを押すとつぶやきの編集のページでつぶやきの内容が表示されます。

 

編集を保存するコントローラ

編集を保存するのは↓のアクションのどれになるか分かりますか?

  • index : つぶやき一覧の表示
  • create : つぶやきの作成
  • show : 複数あるつぶやきの内の1つの表示
  • store : 作成したつぶやきの保存
  • update : つぶやきを編集した時の更新
  • edit : つぶやきの内容の編集
  • destroy : つぶやきの削除

下から3つ目のupdateアクションですよね。

だからPostController.phpのupdateアクションに記述します。

public function update(Request $request, Post $post)
{
  $post->body = $request->body;
  $post->save();
  return redirect('post');
}

1行目の「Post $post」ですがPostモデルを変数$postとして使うという意味です。

2行目の「$post->body」がpostテーブルのbodyカラムという意味で「$request->body」がつぶやきを編集するページで編集した内容(↓の赤枠)という意味です。

だから編集したつぶやきをpostテーブルのbodyカラムに代入する(更新する)となります。

4行目は更新する内容を保存するという意味です。

5行目の「redirect(‘post’)」は「http://localhost:8888/post」にリダイレクトするという意味です。

これでつぶやきの更新が完成しました。

最後はつぶやきの削除です。

 

削除のコントローラ

Postコントローラーに記述する前につぶやきの一覧ページ(index.blade.php)に削除ボタンを作成します。

@extends('layouts.app')
@section('content')
@foreach ($posts as $post)
<div class="container-fluid mt-20" style="margin-left:-10px;">
    <div class="row">
        <div class="col-md-12 w-75 ms-auto me-auto">
            <div class="card mb-2">
                <p>{{$post->body}}</p>
            </div>
            <div class="d-flex">         //この行を追加   
                <a href="{{route('post.edit',$post)}}"><button class="btn btn-primary mb-4">編集</button></a>
                
                
                //ここから追加
                <form method="post" action="" class="ms-1">
                    <button type="submit" class="btn btn-danger" onClick="return confirm('本当に削除しますか?');">削除</button>
                </form>
                //ここまで追加
                
                
            </div>                       //この行を追加
        </div>
    </div>
</div>
@endforeach
@endsection

これで↓の表示になります。

編集ボタン(11行目)はaタグの中に入れましたが削除ボタン(16行目)はformタグの中に入れないといけないのは知っておきましょう。

16行目の「onClick=return confirm(‘本当に削除しますか?’);」ですがjQueryを使っていて削除ボタンを押した時に確認が表示されます。

これを解説しないので気になる人は調べて下さい。

つぶやきを削除するのは↓のアクションのどれになるか分かりますか?

  • index : つぶやき一覧の表示
  • create : つぶやきの作成
  • show : 複数あるつぶやきの内の1つの表示
  • store : 作成したつぶやきの保存
  • update : つぶやきを編集した時の更新
  • edit : つぶやきの内容の編集
  • destroy : つぶやきの削除

一番下ですよね。

だからPostコントローラーのdestroyアクションに記述します。

public function destroy(Post $post)
{
  $post->delete();
  return redirect('post');
}

またindex.blade.phpの削除ボタンを押した時に情報をコントローラーに渡します。


@extends('layouts.app')
@section('content')
@foreach ($posts as $post)
<div class="container-fluid mt-20" style="margin-left:-10px;">
    <div class="row">
        <div class="col-md-12 w-75 ms-auto me-auto">
            <div class="card mb-2">
                <p>{{$post->body}}</p>
            </div>
            <div class="d-flex">       
                <a href="{{route('post.edit',$post)}}"><button class="btn btn-primary mb-4">編集</button></a>
                
                
                //ここから修正
                <form method="post" action="{{route('post.destroy',$post)}}" class="ms-1">
                    @csrf
                    @method('delete')
                    <button type="submit" class="btn btn-danger" onClick="return confirm('本当に削除しますか?');">削除</button>
                </form>
                //ここまで修正
                
                
            </div>
        </div>
    </div>
</div>
@endforeach
@endsection

17行目ですが削除する時は16行目の「@csrf」の下に「@method(delete)」を書くのは知っておきましょう。

これで削除ボタンを押すとつぶやきを削除できます。

これでつぶやきを投稿するアプリの完成です。

 

今回のアプリに関して

今回のアプリはログインしてからつぶやきを作成しましたがログインしなくてもつぶやきを作成できます。

通常はログインしないとつぶやきを作成するページに飛べない様にしますがLaravelに慣れるのを重点に置いているのでログインしなくてもつぶやきを作成できるようにしています。

またログイン機能にlaravel/uiを使っていますがこれは現在Laravel公式で非推奨になっていますがログイン機能の練習と思ってあえて使っています。

私はBreezeでログイン機能を入れていますが練習で導入してみたいという方は使ってみて下さい。

今回のチュートリアルがLaravelの勉強をする人の最初の一歩になれば幸いです。