＜設計＞投稿削除機能

概要
-
【PHP/Laravel】プログラミング初学者によるアプリケーション開発
https://qiita.com/AlpacaFace/items/b8e05a3da599815d8e31

上記トークアプリ開発の設計を説明します。

対象機能
-
- 投稿削除機能

基本設計
-
*** 【定義】　***
- 投稿削除とは、ログインしたユーザーが、自ら投稿したものを削除できる機能。

*** 【仕様】　***
- すでに投稿済みの内容については、削除ボタンからのみ削除可能とし、削除ボタンが表示されていなければ削除を行えないものとする。

- 削除ボタンは、
1. ログイン後のトップページの投稿表示と、
2. ユーザ詳細画面で表示される。
- 削除ボタンにはルーティングの住所が存在しない。

*** 【操作権限】　***

＜まとめ＞投稿削除ボタン操作
![図6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292958/2c8e495a-d79e-cc59-d1b1-9f2252316368.png)





詳細設計
-

*** 【論理削除と物理削除】　***

- サイトの設計思想によって、論理削除を採用するか、物理削除を採用するか、分かれるところです。
- 当初は、一度投稿を削除しても復活できるようにとの意図から論理削除を採用しようとしてSoftdeleteを使う予定でしたが、開発現場でよくある考え方を採用し、プルリクエスト修正の段階で物理削除を採用しました。
- 開発現場でよくある考え方：サーバのデータ容量を節約するため、不要なデータは残しておかない。

*** 【Router】 ***

    （中略）
    
    // ログイン後
    Route::group (['middleware' => 'auth'], function () {
    （中略）
    
        // 投稿画面編集
        Route::prefix('posts')->group(function () {
    
            （中略）
            Route::delete('{id}', 'PostsController@destroy')->name('post.delete');
    
        });
    
    });


*** 【Controller】 ***

app/Http/Controllers/PostsController.php

    public function destroy($id)
    {
        $post = Post::findOrFail($id);

        if (Auth::id() === $post->user_id) {
            $post->delete();
            return redirect("/");
        }

        return App::abort(404);
    }

*** 【Model】***
app/Post.php

    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Post extends Model
    {
        public function user()
        {
            return $this->belongsTo(User::class);

*** 【table】 ***
database/migrations/2023_01_11_234631_create_posts_table.php

    （中略）
                $table->bigInteger('user_id')->unsigned()->index();
                $table->text('content');
                $table->timestamps();
                // 外部キー制約
                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            });

*** 【View】 ***
resources/views/posts/posts.blade.php

    （中略）
     </div>
                    @if(Auth::check() && Auth::user()->id == $post->user_id)
                        <div class="d-flex justify-content-between w-75 pb-3 m-auto">
                            <form method="POST" action="{{ route('post.delete', $post->id) }}">
                                @csrf
                                @method('DELETE')
                                <input type="hidden" name="id" value="DELETE">




動作確認テスト
-

1. テスト用ユーザ1番でログイン後、
トップページのテスト用ユーザ1番の投稿に削除ボタンが表示されることを確認
![Topic Posts.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292958/c2a38d60-c2d8-94a1-e3c3-8f7785cd3019.jpeg)

2. ユーザ詳細画面の削除ボタンが表示されることを確認
![20230302_1 #投稿削除.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292958/3ccee334-74ac-785e-7f38-4bd11ff82f09.jpeg)

3. ユーザ詳細画面からの削除処理の実行
＜削除前＞
![20230302_1 #投稿削除.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292958/2f33e85c-73dd-94f0-18fe-231027eef661.jpeg)

＜削除後＞
![Topic Posts.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292958/c9040bfc-3f27-8f16-79fe-430ac8d24f80.jpeg)

削除後、postsテーブル更新前
![20230302_1 #投稿削除.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292958/fe3e9639-f93a-27fc-63bb-8dc3f938bdea.jpeg)

削除後、postsテーブル更新後。
ユーザ１番の投稿がハードデリートされたことを確認。
![20230302_1 #投稿削除.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292958/9e3ac4a9-6304-3fda-1982-bce2eb0790f9.jpeg)