今回はlaravelのみでいいね機能を実装する方法について解説をします。
TwitterやInstagramなどのSNSでいいね機能みたいな感じと思って
もらえれば大丈夫です。
非同期処理でいいね機能の実装は今回解説はしませんが
まずはlaravelだけでいいね機能を実装する手順について解説をしましょう。
今回作成するイメージについては以下の通りです。
まずいいねを押す前の状態はこちら。
続いていいねを押したあとの状態はいかの画像になります。
いいね機能用のテーブルの作成
Userテーブルと投稿したデータがあるPostテーブルがあるという前提で進めます。
テーブル名はfavoritesとします。
php artisan make:migration create_favorites_table --create=favorites
でmigrationファイルを生成してください。
migration
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateFavoritesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('favorites', function (Blueprint $table) {
$table->increments('id');
$table->bigInteger('user_id')->unsigned()->index();
$table->bigInteger('post_id')->unsigned()->index();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
$table->unique(['user_id','post_id']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('favorites');
}
}
今回外部キーとしていいねをしたユーザのidと投稿に対していいねをした投稿のidを
外部キーを設定します。
該当のレコードが削除された際はいいねをしたレコードを削除するといった感じとなります。
ではmigrationを実行しましょう。
php artisan migrtate
User.phpの編集
中間テーブルのためmodelは作らずに進めます。
user.phpに以下のコードを記述してください。
User.php
public function favorites()
{
return $this->belongsToMany(Post::class, 'favorites', 'user_id', 'post_id')->withTimestamps();
}
public function favorite($postId)
{
$exist = $this->is_favorite($postId);
if($exist){
return false;
}else{
$this->favorites()->attach($postId);
return true;
}
}
public function unfavorite($postId)
{
$exist = $this->is_favorite($postId);
if($exist){
$this->favorites()->detach($postId);
return true;
}else{
return false;
}
}
public function is_favorite($postId)
{
return $this->favorites()->where('post_id',$postId)->exists();
}
favorites()関数 → Userクラスが、favoritesテーブルを通して、Postクラスと繋がっている
ということを表しています。
is_favorite()関数 → 既に「いいね!」しているか?
を判定するための関数も追記しています。
いいね機能用のルート定義
次はルートの定義をしましょう。
web.phpを開いて以下のルートを追加してください。
web.php
Route::post('/{id}/favorite',[App\Http\Controllers\FavoriteController::class, 'store'])->name('favorites.favorite');
Route::delete('/{id}/unfavorite',[App\Http\Controllers\FavoriteController::class, 'destroy'])->name('favorites.unfavorite');
いいね機能用のControllerの作成
次にコントローラを作成しましょう。
php artisan make:controller FavoriteController
FavoriteController
use Illuminate\Support\Facades\Auth;
class FavoriteController extends Controller
{
public function store(Request $request, $id)
{
Auth::user()->favorite($id);
return back();
}
public function destroy($id)
{
Auth::user()->unfavorite($id);
return back();
}
}
先ほどuser.phpに記述した関数を呼び出しています。
Viewの修正
最後にいいねのボタンを設置します。
投稿の一覧画面に設置する想定でコードを記述します。
該当の箇所だけ記載しているのでご自身の環境と合わせて書いてみてください。
index.blade.php
@if (Auth::id() != $p->user_id)
@if (Auth::user()->is_favorite($p->id))
{!! Form::open(['route' => ['favorites.unfavorite', $p->id], 'method' => 'delete']) !!}
{!! Form::submit('いいね!を外す', ['class' => "button btn btn-warning"]) !!}
{!! Form::close() !!}
@else
{!! Form::open(['route' => ['favorites.favorite', $p->id]]) !!}
{!! Form::submit('いいね!を付ける', ['class' => "button btn btn-success"]) !!}
{!! Form::close() !!}
@endif
@endif
下記の判定後、それぞれのボタンを表示しています。
閲覧しているユーザが自分自身でなく、かつ、既に「いいね!」済みの時 → 「いいね!を外す」ボタンを表示
閲覧しているユーザが自分自身でなく、かつ、まだ「いいね!」済みではない時 → 「いいね!を付ける」ボタンを表示
まとめ
今回はlaravelを使っていいね機能の実装方法についての解説でした。
まずはこちらの記事を参考にしていいね機能を作ってみて
もっと手の込んだものにしたい時にjavascriptを使って非同期で
いいね機能を作ると言うのもありだと思います。