DEV Community

Yasser Elgammal
Yasser Elgammal

Posted on • Updated on

How to make Post views count unique in Laravel

Sometimes we need to create count views for Post, Page or Others,
But how to prevent mass views count from one user? And how could this counter be as unique as possible?

In this article, I will show you how you can make views count with solutions to make it as unique as possible,

Here's where we start, here's just an example of our Post migration, to imagine what our database looks like,

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('content');
            $table->string('slug');
            $table->boolean('status');
            $table->integer('views')->default(0);
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('posts');
    }
};
Enter fullscreen mode Exit fullscreen mode

We will discuss in this article two ways to solve mass views as practices:

  • Cookies [ In case of if you have a full stack project Laravel ]
  • Cache

Solution1 (Cookies) -> PostController

class PostController extends Controller
{
    // Get post by it's slug
    public function getPostBySlug($slug)
    {
        $post = Post::whereStatus(true)->whereSlug($slug)->firstOrFail();

        if (!Cookie::get('post_viewed_' . $post->id)) {
            // Update view counter of post
            $post->increment('views');
            // Create a cookie and set it for 1 day
            Cookie::queue('post_viewed_' . $post->id, true, 60 * 24);
        }

        return view('front.post', compact('post'));
    }

}
Enter fullscreen mode Exit fullscreen mode

Solution2 (Cache) -> PostController

class PostController extends Controller
{
    // Get post by it's slug
    public function getPostBySlug($slug)
    {
        $post = Post::whereStatus(true)->whereSlug($slug)->firstOrFail();

    $cacheKey = 'post_viewed_' . $post->id . '_' . request()->ip();
    if (!Cache::has($cacheKey)) {
        // Increment the view count
        $post->increment('views');

        // Set a cache entry to mark that the view has been counted for this visitor
        Cache::put($cacheKey, true, 60 * 24); // Cache for 1 day

        return response()->json(['post' => $post]);
    }

}
Enter fullscreen mode Exit fullscreen mode

Please note: These solutions couldn't completely make views unique, but they help much more to save you from mass views.

Thank you for reading.

Top comments (0)