发布于 2026-01-06 2 阅读
0

使用 Laravel Eloquent Builder 构建更简洁的模型

使用 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();
Enter fullscreen mode Exit fullscreen mode

可以想象,这些方法过一段时间后会导致模型臃肿,但如果我告诉你你可以轻松地清理掉这些模型呢?

编写您自己的 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');
    }
}
Enter fullscreen mode Exit fullscreen mode

如您所见,它使用了与以前相同的方法,因为作用域在后台使用了查询构建器!

注册您的全新 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);
    }
}
Enter fullscreen mode Exit fullscreen mode

使用我们新的构建器

使用全新的查询构建器与使用作用域完全相同。您只需像往常一样将其链接到查询中即可。

Article::published()->get();
Enter fullscreen mode Exit fullscreen mode

最终,功能上没有任何改变,但你的模型变得更加简洁了。

文章来源:https://dev.to/rocksheep/cleaner-models-with-laravel-eloquent-builders-12h4