3-minute essay: Laravel model scope, for you to "save" more code


In principle, the code is written once and referenced everywhere. There is no need for a large number of redundant code. This is a trend and the direction of efforts to improve the robustness of the code.

laravel model provides us with a database operation layer, which separates the data interaction.

But over time, with the increasing demand of the project, the most commonly used query operation will also have a lot of redundant code.

This article will talk about the self slimming of the model and reducing the code of the model.

global scope

Suppose that some database query operations, whether in the controller, in the template file, or in the command line method, have repeated use requirements. If there is a public method in the model, these filter conditions are added by default, which can significantly reduce the amount of code.

For example, there is a query condition:

$publishedEvents = Event::where('published', '=', 1)->get();

The SQL statement finally generated by the above code is as follows:

SELECT * FROM events WHERE `published` = 1;

If the condition published = 1 needs to be enabled by default, we can use the global scope method of laravel model to append this condition to all queries.

The following classes are introduced into the header of the model file Event:

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

Inside the model class, manually implement the boot method:

protected static function boot()
    static::addGlobalScope('published', function (Builder $builder) {
        $builder->where('published', '=', 1);

In this way, the SQL statement where published = 1 will be appended to all model query methods. As long as the QueryBuilder object is created, this constraint statement will be attached.

Some readers may ask, "if I don't want this constraint statement, won't I never even have a model?"

Then where can it be! It's just an element of an attribute array of QueryBuilder. Just remove it manually, so the special case problem can be solved.

$events = Event::withoutGlobalScopes()->get();

You see, it's easy to add and easier to remove.

Local scope

The withoutGlobalScope in the previous section should be shielded manually in different ways each time. Sometimes using a limited scope can better solve the problem. Therefore, the local scope came into being. The method specially used for a model file works when it is called manually. If it is not called, it will not be added actively.

To declare a local scope, just follow the syntax of laravel, as shown in the following example:

public function scopePublished($query)
    return $query->where('published', 1);

Just declare a function method named after a small hump headed by scope and return an instance of QueryBuilder object. When calling, manually append:

$events = Event::published()->get();

The published() method is mapped to the scopePublished method.

The above demonstration code does not receive user input. Here is a demonstration of the transfer method with parameters. For example, there is a query requirement:

$events = Event::where('zip', $zipCode)->get();

Implemented using local scope:

public function scopeZip($query, $zip)
    return $query->where('zip', $zip);

Just pass it in according to the location. Usage, directly passed in:

$zip = '43016';
$events = Event::zip($zip)->get();

This completes the use of local scope. Is it very intuitive.

Since the local scope returns the QueryBuilder instance, you can naturally chain call the methods of the local scope and QueryBuilder. Let's declare another local scope method:

public function scopeAttendees($query, $maximum)
    return $query->where('max_attendees', $maximum);

Now use the above two methods in series:

$events = Event::zip(43016)->attendees(2)->get();

The generated SQL statement is also expected:

SELECT * FROM events WHERE zip = '43016' and max_attendees = '2';

Write at the end

In this issue, we revisit the old story and review the scope design method of laravel model. Two methods are described:

  • Global scope: it works globally and needs to be removed manually;

  • Local scope: only manual calls work, and can be used in a chain;

This design pattern can save query code to a great extent, but for maintenance, developers who are equally familiar with each other need to follow the development specifications and write maintainable code.

Happy coding :-)

I am @Programmer assistant , an original author in IT field who focuses on programming knowledge and has a dynamic circle

Tags: PHP Database Laravel

Posted by Graphi on Fri, 13 May 2022 08:52:39 +0300