Laravel

Laravelでフォロー機能を実装する方法(jQuery、Vue対応)

いつもご利用ありがとうございます。このブログは、広告費によって運営されています。

オススメ本
Web技術を勉強するなら、かなりオススメの雑誌です。毎月新しい発見があります。
読んで損することはない名著。命名で悩むことが多い人はこの本がオススメです。

⇨ Laravel 記事の目次はこちら

Laravel でフォロー機能を実装する方法(jQuery、Vue 対応)について記事にしました。

非同期通信(Ajax 通信)での実装をしています。

実装環境

Laravel Framework 8.*
Laravel Mix v6.0.*

前提

ユーザーの認証機能ができている。

どんな仕様にするか

ユーザーの一覧画面で実装する。

ユーザーの名前の横にフォローボタンがあって、それを押したらフォローできる。

フォローしている人を解除できる。

CSS は省略します。

データベース設計

follow

カラム名は、命名が難しいけど

user_id がフォローしたユーザー

followeduserid がフォローされたユーザー

とします。

データベースのマイグレーションファイルを作成する

※users テーブルは省略します(ほとんどの場合、すでにあると思うので)

follows テーブルを作成する

コマンドを打ちます。

php artisan make:migration create_follows_table

ファイルが作成されました。

databases/migrations/2022_12_29_075711_create_follows_table.php

作成されたマイグレーションファイルを編集する

    public function up()
    {
        Schema::create('follows', function (Blueprint $table) {
            $table->id();
            $table->bigInteger('user_id');
            $table->bigInteger('followed_user_id');
            $table->timestamps();
        });
    }

コマンドでテーブルを作成する

php artisan migrate

以下のようにうまくいけば OK です。

php artisan migrate
Migrating: 2022_12_29_075711_create_follows_table
Migrated:  2022_12_29_075711_create_follows_table (26.20ms)

ユーザーの一覧ページの大枠を作成する

web.php

use App\Http\Controllers\UserController;

Route::get('/users', [ UserController::class, 'index']);

コマンドでコントローラーを作成する

php artisan make:controller UserController

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

App\Http\Controllers\UserController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Models\User;

class UserController extends Controller
{
    public function index()
    {
        $users = User::all();
        return view('user/index',compact('users'));
    }
}

ビューファイルを作成する

resources/views/user/index.blade.php

というフォルダ構成と名前でファイルを作成してください。

index.blade.php を編集する

必要最低限のマークアップだけします。

レイアウト関係は、お好みで調整してください。

@foreach($users as $user)
<div>
  <div>{{$user->name}}</div>
  <button>フォローする</button>
</div>
@endforeach

ユーザーのデータがあれば、こんな感じで表示されます。

follow2

ユーザーのテストデータを入れる方法が分からない場合は、こちらの記事を読んでテストデータを入れてください。

Laravel でテストデータを用意する方法(Seeder の使い方)

大枠が完成しました

いよいよ次の項目から、実際にフォロー機能のための記述をしていきます。

モデルに多対多のリレーションを書く

User モデルと、Follow モデルに多対多のリレーションを書いていきます。

Follow モデルを作成する

コマンドを打ちます。

php artisan make:model Follow

app/Models/Follow.php が作成されました

User モデルにリレーションを書く

App/Models/User.php

    public function follows()
    {
        return $this->belongsToMany('App\Models\User','follows','user_id','followed_user_id');
    }

多対多のリレーションですが、中間テーブルが follows テーブルで命名規則通りに実装できないため、このように実装します。

ここの項目が分からない場合、以下の記事を読んでみてください。

Laravel で多対多のリレーションをして保存、表示する方法【belongsToMany】

フォローするための API を作成する

FollowController を作成する

コマンド

php artisan make:controller FollowController

web.php を編集する

use App\Http\Controllers\FollowController;

Route::group(['middleware' => 'auth'], function () {
    Route::post('/follow/{userId}', [ FollowController::class, 'store']);
});

FollowController.php を編集する

App\Http\Controllers\FollowController.php を編集する

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Auth;

class FollowController extends Controller
{
    public function store($userId)
    {
        Auth::user()->follows()->attach($userId);
        return;
    }
}

これで API が完成しました。

View からこの API を動かす

resouces/views/user/index.blade.php

さっきユーザー一覧を表示するように編集したファイルですが、今回はここに全部書きます。必要に応じて js ファイルを作ったりしてください。

<!-- これがどこかにないとエラーになります -->
<!-- 大抵layouts/app.blade.phpに書かれています -->
<meta name="csrf-token" content="{{ csrf_token() }}" />

@foreach($users as $user)
<div>
  <div>{{$user->name}}</div>
  <button onclick="follow({{ $user->id }})">フォローする</button>
</div>
@endforeach

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script>
  function follow(userId) {
    $.ajax({
      // これがないと419エラーが出ます
      headers: { "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content") },
      url: `/follow/${userId}`,
      type: "POST",
    })
      .done((data) => {
        console.log(data);
      })
      .fail((data) => {
        console.log(data);
      });
  }
</script>

ボタンを押して、エラーが出なくて、データベースの follows テーブルにデータが入っていれば成功です。

ここまでがフォローする機能です。

Laravel で$ is not defined と表示された時の解決方法

Vue の axios で実装する場合

<template>
  <div v-for="user in users">
    <div>{{ user.name }}</div>
    <button @click="follow(user.id)">フォローする</button>
  </div>
</template>

<script>
  export default {
    methods: {
      follow(userId) {
        axios
          .post(`/follow/${userId}`)
          .then(({ data }) => {})
          .catch((err) => {});
      },
    },
  };
</script>

Ajax のときと同じ URL に POST すれば動きます。

csrf 関係でエラーになった場合、下の記事を読んでください。

Laravel と Vue の環境で axios で POST したらエラーになった時の解決方法

エラーが起きたら

401 エラーが出たら?

ログインしてない可能性があります。

ユーザーの認証機能を実装して、ログインしてください。

Laravel で 401 エラーが出て POST やアクセスができない時の対処法

419 エラーが発生したら?

csrf トークンが送信されていません。

view の項目をよく見直してください。

【初心者向け】Laravel で 419 エラーが発生して POST できないとき

500 エラーが発生したら?

さまざまな原因が考えられます。

storage/logs/laravel.log を開いて、エラーログをよく確認してそのエラー内容で調べてください。

フォローを解除する API を作る

web.php

Route::group(['middleware' => 'auth'], function () {
    Route::post('/follow/{userId}', [ FollowController::class, 'store']);
    //追加
    Route::post('/follow/{userId}/destroy', [ FollowController::class, 'destroy']);
});

FollowController.php

    public function destroy($userId)
    {
        Auth::user()->follows()->detach($userId);
        return;
    }
/follow/<<ユーザーID>>/destroy

の URL を POST すればフォロー解除することができます。

補足

もっと良い方法(モデルに処理を書いたりしたい)場合は、この記事を参考にしてみてください

Laravel で「いいね」機能を実装する方法

まとめ

以上です。

長々と大変だったと思いますが、

誰かの参考になればと思います。

このブログは広告のクリックによって支えられています。ありがとうございます。

それでは!

人気記事

PHP7.4 + Laravel6 のプロジェクトを AWS EC2 にデプロイする

【laravel-breadcrumbs】Laravel でパンくずリストを実装する