This content originally appeared on DEV Community and was authored by Marinus van Velzen
Over the past few years I have created tons and tons of models in Laravel. These models have always blown up in size with tons of accessors and added scopes. For the unintroduced, model scopes are methods containing queries that can be chained while retrieving data from the database. In example:
// Models/Article.php
class Article extends Model
{
public function scopePublished(Builder $builder)
{
return $builder->whereNotNull('published_at');
}
}
// usage of the scope
Article::published()->get();
As you might imagine it these methods will add up after a while resulting in bloated models, but what if I tell you that you can clean this up easily?
Writing your own Eloquent Builder
It's possible to create your own Eloquent Builder and bind it to your models. This can be done by creating a class which extends the Eloquent Builder. I'll use the example above for the model that we will clean up. So let's start by creating a ArticleBuilder. It doesn't really matter where you place it, but I tend to create a directory for it in the App namespace.
<?php
declare(strict_types=1);
namespace App\EloquentBuilders;
use Illuminate\Database\Eloquent\Builder;
class ArticleBuilder extends Builder
{
public function published(): self
{
return $this->whereNotNull('published_at');
}
}
As you can see it uses the same methods of before, because the scope uses a query builder in the background!
Registering your brand new Eloquent Builder
Now all that's left is to bind our custom query builder to the Article Model. This can be done by overriding the newEloquentBuilder method. After overriding it you can remove any of the old scopes. Your end result will look something like this!
<?php
declare(strict_types=1);
namespace App\Models;
use App\EloquentBuilders\ArticleEloquentBuilder;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
use HasFactory;
public function newEloquentBuilder($query): Builder
{
return new ArticleEloquentBuilder($query);
}
}
Using our new builder
Using your brand new query builder is just the same as with the scopes. All you need to do is chain it on your query like you usually do.
Article::published()->get();
In the end nothing changed functionality wise, but your model just became a lot cleaner.
This content originally appeared on DEV Community and was authored by Marinus van Velzen
Marinus van Velzen | Sciencx (2021-09-05T14:02:44+00:00) Cleaner models with Laravel Eloquent Builders. Retrieved from https://www.scien.cx/2021/09/05/cleaner-models-with-laravel-eloquent-builders/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.