今回はlaravelのみでフォロー機能を実装する方法について解説をします。
TwitterやInstagramなどのSNSでのフォロー機能みたいな感じと思って
もらえれば大丈夫です。
今回作るフォロー機能の概要として
自分自身のフォローはできず、フォローをしていない場合はフォローボタンが表示され
フォローをしていたらフォロー解除ボタンが表示されるといった感じになります。
フォロー機能用のMigrationファイルの作成
フォロー機能のmigrationファイルを作成します。
php artisan make:migration create_follows_table --create=followers
migration
Schema::create('followers', function (Blueprint $table) {
$table->unsignedInteger('following_id')->comment('フォローしているユーザID');
$table->unsignedInteger('followed_id')->comment('フォローされているユーザID');
$table->index('following_id');
$table->index('followed_id');
$table->unique([
'following_id',
'followed_id'
]);
});
フォローをしているユーザidと
フォローされているユーザidを記録しています。
ここでmigraionを実行しましょう。
php artisan migrate
フォローモデルの作成
フォローモデルを作成しましょう。
php artisan make:model Follow
app/Models配下のFollow.phpを開いて以下のように追記してください。
Follow.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Follower extends Model
{
protected $primaryKey = [
'following_id',
'followed_id'
];
protected $fillable = [
'following_id',
'followed_id'
];
public $timestamps = false;
public $incrementing = false;
}
timestampとidのインクリメントを無効にしています。
次にapp/Models配下のUser.phpを開いてリレーションの設定を行います。
User.php
public function followers()
{
return $this->belongsToMany(User::class, 'followers', 'followed_id', 'following_id');
}
public function follows()
{
return $this->belongsToMany(User::class, 'followers', 'following_id', 'followed_id');
}
次にコントローラにアクションを定義します。
今回はUserControllerに定義しますがこちらはご自身の環境に合わせて変更してください。
UserController
public function follow(User $user)
{
$follower = auth()->user();
// フォローしているか
$is_following = $follower->isFollowing($user->id);
if(!$is_following) {
// フォローしていなければフォローする
$follower->follow($user->id);
return back();
}
}
// フォロー解除
public function unfollow(User $user)
{
$follower = auth()->user();
// フォローしているか
$is_following = $follower->isFollowing($user->id);
if($is_following) {
// フォローしていればフォローを解除する
$follower->unfollow($user->id);
return back();
}
}
次にアクション内に記述した関数をUser.phpに定義します。
以下のように記述してください。
User.php
// フォローする
public function follow($user_id)
{
return $this->follows()->attach($user_id);
}
// フォロー解除する
public function unfollow($user_id)
{
return $this->follows()->detach($user_id);
}
// フォローしているか
public function isFollowing($user_id)
{
return (boolean) $this->follows()->where('followed_id', $user_id)->first(['id']);
}
// フォローされているか
public function isFollowed($user_id)
{
return (boolean) $this->followers()->where('following_id', $user_id)->first(['id']);
}
フォロー用のルート定義
ここまでできたら次にルート定義をします。
web.phpを開いてください。
web.php
Route::post('users/{user}/follow', [App\Http\Controllers\UserController::class, 'follow'])->name('follow');
Route::delete('users/{user}/unfollow',[App\Http\Controllers\UserController::class, 'unfollow'])->name('unfollow');
Viewの修正
最後にViewの修正です。
今回私はユーザページにフォローボタンを置くことにしているのでshow.blade.phpとなります。
show.blade.php
<div class="d-flex justify-content-end flex-grow-1">
@if(Auth::id() != $user_flg)
@if (Auth::user()->isFollowing($user->id))
<form action="{{ route('unfollow', ['user' => $user->id]) }}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit" class="btn btn-danger">フォロー解除</button>
</form>
@else
<form action="{{ route('follow', ['user' => $user->id]) }}" method="POST">
{{ csrf_field() }}
<button type="submit" class="btn btn-primary">フォローする</button>
</form>
@endif
@endif
@if(Auth::id() != $user_flg)に関しては訪れたユーザページがログインしているユーザのページじゃなければ
フォローができるといった形となります。
もし同じように実装したい方は以下のように記述してください。
UserController
public function show(Request $request,$id){
$user = User::find($id);
$user_flg = $request->path();
$user_flg = preg_replace('/[^0-10000]/', '', $user_flg);
return view('user.show',['user' => $user,'user_flg' => $user_flg]);
}
まとめ
今回はlaravelを使ってフォロー機能の実装方法について解説をしました。
YoutubeでもlaravelのSNSアプリの作り方を解説しているのでもしよかったら
みてみてください!