I'm watching the Laracasts: Laravel 5.4 from Scratch series, and have come across the concept of query scopes.
In the video, we set up a class like this:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
public function scopeIncomplete($query)
{
return $query->where('completed', 0);
}
}
My first question:
Why is a method like: public function scopeIncomplete($query)
called like this: App\Task::incomplete()
with the ::
operator?
Isn't that a non-static method being called statically?
My second question:
Where does $query
come from?
From what I can understand this is the "existing" query, but it is called like this: App\Task::incomplete()->where('id', '>', 1)->get();
So I'm not really sure where this variable is coming from.
Maybe it's explained more in depth later but I can't wrap my head around how this works.
You can use Laravel scopes to DRY up the code. The scope is just a method that you can use in your model to encapsulate the syntax used to execute a query such as above. Scopes are defined by prefixing the name of a method with scope, as below.
In Laravel the database query builder provides an easy interface to create and run database queries. It can be used to perform all the database operations in your application, from basic DB Connection, CRUD, Aggregates, etc. and it works on all supported database systems like a champ.
Global Scope is a very important concept of laravel 6. using Global Scope you can reuse same eloquent condition in laravel application. i also written tutorial of how to create local scope in laravel 6. Local scope it only for single model. But you define global scope then you can use with all model.
Laravel global scopes allow us to add constraints to all queries for a given model. You know that Laravel's own soft delete functionality utilizes global scopes to only pull "non-deleted" models from the database.
This is pretty broad since it is covering two large topics on Eloquent.
The first refers to Eloquent's use of the facade pattern to pass static calls to non-static methods.
The facade pattern utilizes the IoC container to pass a method call to a bound, or new, instance of a class.
The facade pattern makes use of overloading and the magic method __callStatic.
The second question refers to Eloquent's overloading that passes the unregistered method calls to a query builder object (specifically \Illuminate\Database\Eloquent\Builder). This is what allows for where() and various other Query Builder methods to be called on the Eloquent model itself. Inside the Model class, you can see:
/**
* Handle dynamic method calls into the model.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
if (in_array($method, ['increment', 'decrement'])) {
return $this->$method(...$parameters);
}
return $this->newQuery()->$method(...$parameters);
}
Since where() or incomplete() are not defined in Model, they'll be passed to the Builder class, which is returned by Model::newQuery().
Inside the Builder __call method, you have:
if (method_exists($this->model, $scope = 'scope'.ucfirst($method))) {
return $this->callScope([$this->model, $scope], $parameters);
}
So this is checking for the scopes defined inside the model and passing the $parameters which includes this Builder instance.
So in summary, the call for Model::incomplete() will go:
Model __call() -> Builder __call() -> Model scopeIncomplete(Builder $builder)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With