使用 Laravel Eloquent Builder 构建更简洁的模型
过去几年,我在 Laravel 中创建了海量的模型。这些模型总是因为大量的访问器和附加的作用域而变得异常庞大。对于不熟悉模型作用域的人来说,它们指的是包含查询语句的方法,这些查询语句可以在从数据库检索数据时链式调用。例如:
// Models/Article.php
class Article extends Model
{
public function scopePublished(Builder $builder)
{
return $builder->whereNotNull('published_at');
}
}
// usage of the scope
Article::published()->get();
可以想象,这些方法过一段时间后会导致模型臃肿,但如果我告诉你你可以轻松地清理掉这些模型呢?
编写您自己的 Eloquent Builder
您可以创建自己的 Eloquent Builder 并将其绑定到您的模型。这可以通过创建一个继承 Eloquent Builder 的类来实现。我们将使用上面的示例来清理模型。那么,让我们从创建一个 ArticleBuilder 开始。它的位置其实并不重要,但我通常会在 App 命名空间中创建一个目录来存放它。
<?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');
}
}
如您所见,它使用了与以前相同的方法,因为作用域在后台使用了查询构建器!
注册您的全新 Eloquent Builder
现在剩下的就是将自定义查询构建器绑定到文章模型。这可以通过重写 `newEloquentBuilder` 方法来实现。重写之后,您可以移除所有旧的作用域。最终结果看起来会像这样!
<?php
declare(strict_types=1);
namespace App\Models;
use App\EloquentBuilders\ArticleBuilder;
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 ArticleBuilder($query);
}
}
使用我们新的构建器
使用全新的查询构建器与使用作用域完全相同。您只需像往常一样将其链接到查询中即可。
Article::published()->get();
最终,功能上没有任何改变,但你的模型变得更加简洁了。
文章来源:https://dev.to/rocksheep/cleaner-models-with-laravel-eloquent-builders-12h4