「いいね」機能をつける場合、ログインユーザーのみが「いいね」できるようにする方法が一般的ですが、ログインなしの場合でも可能です。
今回は、前半はログインしているユーザー用の「いいね」機能について解説します。
後半は、ここにログインなしユーザーの「いいね」も反映されるようにしていきます。
ログインなしの場合は、IPアドレスを使って、ユーザーを識別します。
Laravelの醍醐味のひとつは、リレーション。
今回はリレーションをフル活用して、機能を搭載していきますね。
Laravel いいね機能追加・ログインユーザー用
まずはログインユーザーのみが「いいね」できる機能を搭載します。
今回は、すでにUserモデルとPostモデルがあるとします。UserモデルとPostモデルに多対多リレーションを設定していきます。
① 中間テーブルを作成
PostとUserの中間テーブルを作成します。
1 |
php artisan make:migration create_post_user_table |
マイグレーションファイルには、次のようにいれます。
1 2 3 4 5 6 7 8 9 |
public function up() { Schema::create('nices', function (Blueprint $table) { $table->id(); $table->foreignId('post_id'); $table->foreignId('user_id'); $table->timestamps(); }); } |
マイグレートを実行します。
1 |
php artisan migrate |
② リレーションを設定
多対多リレーションを設定します。
【Userモデルファイル】
1人ユーザーが複数の投稿をする可能性があるので、Postモデルに対して、すでにhasManyメソッドを設定がされているとします。
さらに、1人のユーザーが複数の投稿にに対して「いいね」をする可能性があるので、多対多リレーションを設定し、belongsToManyメソッドを設定します。
1 2 3 4 5 6 7 8 |
public function posts() { return $this->hasMany(Post::class); } public function favorites() { return $this->belongsToMany(Post::class); } |
【Postモデルファイル】
ひとつの投稿は、ひとりのユーザーに紐づくので、Postモデルに対して、すでにbelongsToメソッドを設定されているとします。
さらに、ひとつの投稿は、複数のユーザーの「いいね」を獲得する可能性があるので、多対多リレーションを設定し、belongsToManyメソッドを設定します。
1 2 3 4 5 6 7 8 |
public function user() { return $this->belongsTo(User::class); } public function followers() { return $this->belongsToMany(User::class); } |
③ ルートファイルの設定
今回は既にある投稿表示用の画面に「いいね」機能を搭載することにします。
新たに 下記のルート設定を加えます。
【routes/web.php】
1 2 3 4 5 |
use App\Http\Controllers\PostController; (省略) Route::post('/post/{post}/like', [PostController::class, 'like'])->name('post.like'); |
④ コントローラーの作成
「いいね」を付け足し消したりする処理を記述するため、PostContollerに処理を加えます。もしまだコントローラがなければ、作成します。
1 |
php artisan make:controller PostController |
PostControllerを開き、上部に、use宣言を追加しておきましょう。
1 2 3 4 |
namespace App\Http\Controllers; use Illuminate\Http\Request; // use宣言追加 use App\Models\Post; |
次に「いいね」をつけるためにlikeメソッドを入れます。もし「いいね」があれば、いいねを外す、なければ追加するようにしました。
【PostController likeメソッド】
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public function like(Post $post) { $user = auth()->user(); $isLiked = $user->favorites()->where('post_id', $post->id)->exists(); if ($isLiked) { $user->favorites()->detach($post); } else { $user->favorites()->attach($post); } return back(); } |
⑥ビューファイルの作成
最後は、見える部分を作っていきます。
既にある投稿一覧用のビューファイルに、次のように、「いいね」ボタンを設置します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<x-app-layout> <x-slot name="header"> <h2 class="font-semibold text-xl text-gray-800 leading-tight"> 投稿一覧 </h2> </x-slot> <div class="container mx-auto mt-8"> <table class="table-auto w-full"> <thead> <tr class="bg-gray-200"> <th class="px-4 py-2">ID</th> <th class="px-4 py-2">本文</th> <th class="px-4 py-2">いいね</th> </tr> </thead> <tbody> @foreach ($posts as $post) <tr class="border-b border-gray-200 hover:bg-gray-100"> <td class="px-4 py-2">{{ $post->id }}</td> <td class="px-4 py-2">{{ $post->body }}</td> <td class="px-4 py-2"> <form action="{{ route('post.like', $post) }}" method="POST"> @csrf <button type="submit" class="{{ $post->followers->contains(auth()->user()) ? 'bg-red-500 hover:bg-red-700' : 'bg-blue-500 hover:bg-blue-700' }} text-white font-bold py-2 px-4 rounded"> {{ $post->followers->contains(auth()->user()) ? 'いいね取り消し' : 'いいね' }} </button> </form> {{ $post->followers->count() }} </td> </tr> @endforeach </tbody> </table> </div> </x-app-layout> |
⑦ テストしてみる
では、テストしてみます。「いいね」前は、こんな表示。
「いいね」をすると、こうなります。「いいね取り消し」を押すと、再度「いいね」となります。
外見なども変えて、すてきな「いいね」機能つけてみてくださいね