#概要
Laravel x Vue.js(Vuex)でSPAに対応したフォロー機能を実装します。
今回はLaravel部分だけの実装になります。
フロントの実装はこちら→フォロー機能の実装② ~フロントエンド~
最終的なUIはこんな感じ↓
フォローボタンを押したらフォローできて、フォロー解除を押したらフォロー解除するだけです。
##バージョン
Laravel 8.12
Vue.js 2.5.17
Vuex 3.6.0
Vue Router 3.4.9
#実装
##テーブルの作成
xxxx_xx_xx_xxxxxxx_create_follow_users_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateFollowUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('follow_users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('followed_user_id')->index();
$table->unsignedBigInteger('following_user_id')->index();
$table->timestamps();
$table->foreign('followed_user_id')
->references('id')
->on('users')
->cascadeOnDelete();
$table->foreign('following_user_id')
->references('id')
->on('users')
->cascadeOnDelete();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('follow_users');
}
}
mysql> desc follow_users;
+-------------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+-----------------+------+-----+---------+----------------+
| id | bigint unsigned | NO | PRI | NULL | auto_increment |
| followed_user_id | bigint unsigned | NO | MUL | NULL | |
| following_user_id | bigint unsigned | NO | MUL | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+-------------------+-----------------+------+-----+---------+----------------+
5 rows in set (0.19 sec)
followed_user_id:フォローされているユーザー
following_user_id:フォローしているユーザー
##Userモデルに追加
Models/User.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
'login_id',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/*
*フォローされているユーザーを取得
*/
public function followUsers()
{
return $this->belongsToMany(
'App\Models\User',
'follow_users',
'followed_user_id',
'following_user_id'
);
}
/*
*フォローしているユーザーを取得
*/
public function follow()
{
return $this->belongsToMany(
'App\Models\User',
'follow_users',
'following_user_id',
'followed_user_id'
);
}
}
}
多対多のテーブルになるので、両方ともbelongsToManyで取得する。
##コントローラ の作成
FollowUserController.php
<?php
namespace App\Http\Controllers;
use App\Models\FollowUser;
use App\Models\User;
use Illuminate\Http\Request;
class FollowUserController extends Controller
{
//フォローする
public function follow(Request $request)
{
FollowUser::firstOrCreate([
'followed_user_id' => $request->post_user,
'following_user_id' => $request->auth_user
]);
return true;
}
//フォロー解除する
public function unfollow(Request $request)
{
$follow = FollowUser::where('followed_user_id', $request->post_user)
->where('following_user_id', $request->auth_user)
->first();
if ($follow) {
$follow->delete();
return false;
}
}
}
unfollow()では先にこのレコードが存在するのか確認してから削除処理を行いました。
返り値をbooleanで返すことで、フロント実装の際にフォローしているかしていないかの確認をします。
#まとめ
これでバックエンドの処理は終わりなので、次はフロントの処理を書こうと思います。