DEV Community

David Carr
David Carr

Posted on • Originally published at dcblog.dev on

Adding pinned posts with Laravel

Adding pinned posts with Laravel

Let's say you have a blog and have posts ordered by their published date. Later you decide you want to pin certain posts.

Pinned posts should be displayed before any other posts regardless of their published date.

The Solution

You can accomplish this by modifying the order clause in the query.

Take this order:

->orderBy('published_at', 'desc')
Enter fullscreen mode Exit fullscreen mode

This will order posts by their published date in descending order.

Adding a second-order clause:

->orderBy('is_pinned', 'desc')->orderBy('published_at', 'desc');
Enter fullscreen mode Exit fullscreen mode

This time ordered by a is_pinned column then order by the published_at column.

This will show the posts pinned first and then show the posts in their published order.

The Setup

Adding a migration to add a column called is_pinned to a posts table

php artisan make:migration add_pinned_field_to_posts
Enter fullscreen mode Exit fullscreen mode

Migration

<?php

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

class AddPinnedFieldToPosts extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->boolean('is_pinned')->default(false);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->dropColumn('is_pinned');
        });
    }
}
Enter fullscreen mode Exit fullscreen mode

Create a local scope

In the post model, create a local scope for the order.

public function scopeOrder($query)
{
    return $query->orderBy('is_pinned', 'desc')->orderBy('published_at', 'desc');
}
Enter fullscreen mode Exit fullscreen mode

Using the local scope

When querying the posts use the order scope to set the order for both is_pinned and published_at

Post::order()->paginate();
Enter fullscreen mode Exit fullscreen mode

Top comments (0)