2

我需要覆盖上述方法以跳过一些数据库记录。使用where不是一个选项,因为我必须每次都使用它,因为数据库中有我大部分时间不需要的记录,并且我不允许从数据库中删除它们。这是我这样做的尝试:

class SomeTable extends BaseModel { 

    public static function first() {
       $query = static::query();
       $data = $query->first();
       if($data && $data->type == 'migration_type') return null;

       return $data;
    }

    public static function get() {
       $query = static::query();
       $data = $query->get();
       foreach($data as $key => $item) {
           if($item->type == 'migration_type') unset($data[$key]); 
       }

       return $data;
    }
}

此代码的问题在于它仅在模型上直接调用时才有效。如果我正在使用其他一些函数,例如where,之前getfirst方法,它只会跳过我覆盖的方法。这样做的正确方法是什么,我应该将此代码放在模型中吗?

我的问题与上述问题的答案不重复,据说:

从扩展您的 CustomModel 的模型进行的所有查询都将获得这个新方法

而且我只需要为特定模型覆盖这两个函数,而不是应用程序中的每个函数,因为并非所有表都有type列。这就是我在模型类中编写它们的原因。

4

3 回答 3

4

我需要覆盖上述方法以跳过一些数据库记录。

考虑模型上的全局查询范围。

https://laravel.com/docs/5.8/eloquent#global-scopes

全局范围允许您为给定模型的所有查询添加约束。Laravel 自己的软删除功能利用全局范围仅从数据库中提取“未删除”模型。编写自己的全局作用域可以提供一种方便、简单的方法来确保给定模型的每个查询都接收到某些约束。

于 2019-04-15T14:07:37.200 回答
0

这里的问题是模型上的 where() 方法返回一个QueryBuilder实例,而 get() 将返回一个Collection实例。

您应该能够通过在其位置添加一个宏来覆盖集合的默认方法,并且可以这样做......

Collection::macro('toUpper', function () {
    return $this->map(function ($value) {
        return Str::upper($value);
    });
});

扩展查询构建器实例并不是那么容易,但这里有一个很好的教程,它涉及覆盖应用程序的默认连接类,这对于未来的升级来说并不是很好。

于 2019-04-15T14:04:29.477 回答
-1

因为在调用你正在处理数据库构建器的地方之后,你的模型中的这些方法没有被调用..关于这个问题你可能会通过使用select而不是first直接来解决它,所以将处理构建器..

例子:

SomeTable::select('col1','col2')->take(1)->get();

如果您正在与同一个项目的其他开发人员一起工作,那么覆盖这些方法的另一件事不是一个好主意。

祝你好运

于 2019-04-15T13:54:32.400 回答