Laravelでコメント機能を実装する

# はじめに
Web系自社開発企業への転職を目標にLaravel+VuejsでWebアプリケーションを作成しています！
今回は、Laravelでコメント機能を実装するまでの流れを解説していきます。


# 目次
<!-- タイトルとアンカー名を編集 -->
1. [モデルを作成](#Chapter1)
2. [リレーションを設定](#Chapter2)
3. [ルーティングを追加](#Chapter3)
4. [コントローラーを作成](#Chapter4)
5. [ビューを作成](#Chapter5)
6. [参考教材](#reference) 

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# モデルを作成

- Commentモデルとマイグレーションファイルの作成

```
php artisan make:model Comment --migration
```

- マイグレーションを編集

```php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCommentsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('comment');
            $table->bigInteger('article_id')->unsigned();
            $table->foreign('article_id')
                ->references('id')
                ->on('articles')
                ->onDelete('cascade');
            $table->bigInteger('user_id')->unsigned();
            $table->foreign('user_id')
                ->references('id')
                ->on('users')
                ->onDelete('cascade');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('comments');
    }
}
```

- マイグレーションファイルを実行してcommentsテーブルを作成

```
php artisan migrate
```

<a id="#Chapter2"></a>
# リレーションの設定

```php:Comment.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    protected $fillable = [
        'comment',
        'article_id',
        'user_id',
    ];

    public function article()
    {
        return $this->belongsTo('App\Article');
    }

    public function user()
    {
        return $this->belongsTo('App\User');
    }
}
```

```php:Article.php
public function comments(): HasMany
{
    return $this->hasMany('App\Comment');
}
```

```php:User.php
public function comments(): HasMany
{
    return $this->hasMany('App\Comment');
}
```

<a id="#Chapter3"></a>
# ルーティングの追加

```php:web.php
//コメント投稿処理
Route::post('/articles/{comment_id}/comments','CommentsController@store');

//コメント取消処理
Route::get('/comments/{comment_id}', 'CommentsController@destroy');
```

<a id="#Chapter4"></a>
# コントローラーの作成

- 以下のコマンドを実行してコントローラーを作成する

```
php artisan make:controller CommentsController
```

- 作成したコントローラーにアクションを追加

```php:CommentsController.php
class CommentsController extends Controller
{
    public function __construct()
    {
        // ログインしていなかったらログインページに遷移する（この処理を消すとログインしなくてもページを表示する）
        $this->middleware('auth');
    }

   public function store(Request $request)
   {
       $comment = new Comment();
       $comment->comment = $request->comment;
       $comment->article_id = $request->article_id;
       $comment->user_id = Auth::user()->id;
       $comment->save();

       return redirect('/');
   }

    public function destroy(Request $request)
    {
        $comment = Comment::find($request->comment_id);
        $comment->delete();
        return redirect('/');
    }
}
```

<a id="#Chapter5"></a>
# ビューを作成

```php:card.blade.php
<div class="card-body line-height">
    <div id="comment-article-{{ $article->id }}">
        @include('articles.comment_list')
    </div>
    <a class="light-color post-time no-text-decoration" href="/articles/{{ $article->id }}">{{ $article->created_at }}</a>
    <hr>
    <div class="row actions" id="comment-form-article-{{ $article->id }}">
        <form class="w-100" id="new_comment" action="/articles/{{ $article->id }}/comments" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" />
            {{csrf_field()}}
            <input value="{{ $article->id }}" type="hidden" name="article_id" />
            <input value="{{ Auth::id() }}" type="hidden" name="user_id" />
            <input class="form-control comment-input border-0" placeholder="コメント ..." autocomplete="off" type="text" name="comment" />
        </form>
    </div>
</div>
```

```php:comment_list.blade.php
@foreach ($article->comments as $comment)
  <div class="mb-2">
        <span>
            <strong>
                <a class="no-text-decoration black-color" href="{{ route('users.show', ['name' => $comment->user->name]) }}">{{ $comment->user->name }}</a>
            </strong>
        </span>
        <span>{{ $comment->comment }}</span>
        @if ($comment->user->id == Auth::id())
            <a class="delete-comment" data-remote="true" rel="nofollow" data-method="delete" href="/comments/{{ $comment->id }}">
                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-x" viewBox="0 0 16 16">
                    <path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
                </svg>
            </a>
        @endif
  </div>
@endforeach
```

<a id="#reference"></a>
# 参考教材

https://www.techpit.jp/courses/18

https://www.techpit.jp/courses/11