In this section, we will create like and unlike buttons for posts in Laravel. For this tutorial, we will use Laravel along with the rtconner/laravel-likeable
package. For authentication, we will use Laravel Breeze.
Step 1: Create Laravel Project
Installing a fresh new laravel application.
composer create-project --prefer-dist laravel/laravel project-name
Step 2: Set Up Database Details in ENV
Now, you have to connect the laravel app to the database, hence open the .env configuration file and add the database credentials as suggested below.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=database_user_name
DB_PASSWORD=database_password
Step 3: Install breeze
You need to install first breeze package.
composer require laravel/breeze --dev
Then, install breeze ui.
php artisan breeze:install
You can install dependencies.
npm install && npm run dev
Step 4 : Create post model and table
php artisan make:model Post -m
migration file.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
app/Models/Post.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'title',
'description'
];
}
Step 5: Install Laravel Likeable Package
composer require rtconner/laravel-likeable
Simple Usage
$post->like(); // like the post for current user
$post->like($myUserId); // pass in your own user id
$post->like(0); // just add likes to the count, and don't track by user
$post->unlike(); // remove like from the post
$post->unlike($myUserId); // pass in your own user id
$post->unlike(0); // remove likes from the count -- does not check for user
$post->likeCount; // get count of likes
$post->likes; // Iterable Illuminate\Database\Eloquent\Collection of existing likes
$post->liked(); // check if currently logged in user liked the post
$post->liked($myUserId);
post::whereLikedBy($myUserId) // find only posts where user liked them
->with('likeCounter') // highly suggested to allow eager load
->get();
Migrate database
php artisan migrate
Setup your models
<?php
namespace App\Models;
use Conner\Likeable\Likeable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory, Likeable;
protected $fillable = [
'title',
'description'
];
}
Create Post Controller
php artisan make:controller PostController
app/Http/Controllers/PostController.php
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function postList()
{
$posts = Post::all();
return view('posts.post-list',compact('posts'));
}
public function likePost($id)
{
$post = Post::find($id);
$post->like();
$post->save();
return redirect()->route('post.list')->with('message','Post Like successfully!');
}
public function unlikePost($id)
{
$post = Post::find($id);
$post->unlike();
$post->save();
return redirect()->route('post.list')->with('message','Post Like undo successfully!');
}
}
Create Routes
<?php
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::get('/post-list',[PostController::class,'postList'])->name('post.list');
Route::post('/like-post/{id}',[PostController::class,'likePost'])->name('like.post');
Route::post('/unlike-post/{id}',[PostController::class,'unlikePost'])->name('unlike.post');
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth'])->name('dashboard');
require __DIR__ . '/auth.php';
Step 6 : Create View File
resources/views/post/post-list.blade.php
<x-app-layout>
<x-slot name="header">
<h2 class="text-xl font-semibold leading-tight text-gray-800">
PostList
</h2>
</x-slot>
<div class="py-12">
<div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
<div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
<div>
<h4 class="mb-4 text-2xl font-bold">Post </h4>
@if (session()->has('message'))
<div class="px-4 py-4 text-green-800 bg-green-200 border-l-4 border-green-900 rounded">
{{ session('message') }}
</div>
@endif
<div>
<div class="flex flex-col mt-8">
<div class="py-2">
<div class="min-w-full border-b border-gray-200 shadow">
<table class="min-w-full">
<thead>
<tr>
<th
class="px-6 py-3 text-left text-gray-500 border-b border-gray-200 bg-gray-50">
#
</th>
<th
class="px-6 py-3 text-left text-gray-500 border-b border-gray-200 bg-gray-50">
Title
</th>
<th
class="px-6 py-3 text-left text-gray-500 border-b border-gray-200 bg-gray-50">
Description
</th>
<th
class="px-6 py-3 text-left text-gray-500 border-b border-gray-200 bg-gray-50">
Action
</th>
</tr>
</thead>
<tbody class="bg-white">
@foreach($posts as $post)
<tr>
<td class="px-6 py-4 border-b border-gray-200">
<div class="flex items-center">
<div class="ml-4">
<div class="text-sm text-gray-900">
{{ $post->id }}
</div>
</div>
</div>
</td>
<td class="px-6 py-4 border-b border-gray-200">
<div class="text-sm text-gray-900">
{{ $post->title }}
</div>
</td>
<td class="px-6 py-4 border-b border-gray-200">
{{ $post->description }}
</td>
<td
class="px-6 py-4 text-sm text-gray-500 border-b border-gray-200 ">
<form action="{{ route('like.post', $post->id) }}"
method="post">
@csrf
<button
class="{{ $post->liked() ? 'bg-blue-600' : '' }} px-4 py-2 text-white bg-gray-600">
like {{ $post->likeCount }}
</button>
</form>
</td>
<td
class="px-6 py-4 text-sm text-gray-500 border-b border-gray-200">
<form action="{{ route('unlike.post', $post->id) }}"
method="post">
@csrf
<button
class="{{ $post->liked() ? 'block' : 'hidden' }} px-4 py-2 text-white bg-red-600">
unlike
</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</x-app-layout>