How to Use Global Scope in Laravel?

Global scope is a very important concept out of the box in Laravel. Basically we can attach some sort of additional requirements with our Laravel Eloquent queries by using Global scope. If you are still confused then let me explain with real world scenario and code.

Imagine we are having a books table in our database. We want to show only those books to our users which are available. So normal query will be.

$books = Book::where('available', true)->get();

Now we want to use this query everywhere but our main query will return all books.

$books = Book::all();

This query will return all books, both available and not available.

Now using global scope we can change the behaviour of our main query and eliminate not available books from our all() query. So code in our create_books migration will be.

<?php

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

class CreateBooksTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('books', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('language');
            $table->string('thumbnail');
            $table->boolean('available');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('books');
    }
}

Now we will create a new file in our app/scopes folder.

<?php

namespace App\Scopes;

use \Illuminate\Database\Eloquent\Builder;
use \Illuminate\Database\Eloquent\Scope;
use \Illuminate\Database\Eloquent\Model;

class ExcludeBookWhenNotAvailable implements Scope {
	/**
	 * @inheritdoc
	 *
	 * @param Builder $builder
	 * @param Model $model
	 *
	 * @return Builder|void
	 */
	public function apply( Builder $builder, Model $model ) {
		return $builder->where( 'available', '=', true );
	}
}

Here in this file we are eliminating not available books using query builder. And this is the code in our Book.php file.

<?php

namespace App;

use App\Scopes\ExcludeBookWhenNotAvailable;
use Illuminate\Database\Eloquent\Model;

class Book extends Model {

	/**
	 * @inheritdoc
	 *
	 * @var string[]
	 */
	protected $fillable = [
		'title',
		'language',
		'thumbnail',
		'available'
	];

	/**
	 * @inheritdoc
	 *
	 * @return void
	 */
	protected static function boot() {
		parent::boot();
		static::addGlobalScope( new ExcludeBookWhenNotAvailable() );
	}
}

Now we are adding Global scope in our boot() method here. Now if we will use Book::all() query then it will only return available books.

I hope now you understand everything about Global scope in Laravel. If you have any questions please leave a comment in the comments section below.