为 Laravel 关系返回 null 而不是“调用未定义的关系”错误

Posted

技术标签:

【中文标题】为 Laravel 关系返回 null 而不是“调用未定义的关系”错误【英文标题】:Returning null instead of "Call to undefined relationship" error for Laravel relationships 【发布时间】:2021-02-05 23:49:22 【问题描述】:

当我将 ModelName::with('somerelation')->get() 与 Laravel Eloquent 一起使用时,如果模型没有这种关系,我会收到 Call to undefined relationship [somerelation] on model [App\SomeModel] 错误。

但是对于多态关系,我收集了所有相关模型,如果没有定义关系,我想使用with('somerelation') 并获取null。有什么方法可以避免错误并从 with() 中返回 null 或任何有条件地使用 with 的方法?

【问题讨论】:

【参考方案1】:

@Leonardo Oberle 之前的回答对我不起作用。 我一直在努力寻找一种方法来验证传递给with() 方法的关系字符串的完整性,因此它只会在关系存在时加载关系,并且如果缺少某些内容也不会抛出错误。

所以,我最终创建了一个抽象 Model 类,它从 EloquentModel 扩展而来,并覆盖了 with() 方法,就像在 Leonardo Oberle's 响应中一样。

唯一的问题是方法的代码应该是这样的:

namespace App;

use Illuminate\Database\Eloquent\Model as EloquentModel;
use Illuminate\Database\Eloquent\RelationNotFoundException;

abstract class Model extends EloquentModel

    public static function with($relations)
    
        $filteredRelations = $this->relationExistsUntil($relations);

        parent::with($filteredRelations);

    



    /**
     * @param string $with
     * @return string
     */
    protected function relationExistsUntil(string $with): string
    
        $model = $this;
        $result = '';
        $relationParts = explode('.', $with);

        foreach ($relationParts as $relationPart) 
            $isValidRelation = method_exists($model, $relationPart) && $model->$relationPart() instanceof Relation;

            if (!$isValidRelation) 
                break;
            

            $result .= empty($result) ? $relationPart : ".$relationPart";
            $model = ($model->$relationPart()->getRelated());
        

        return $result;
    



So, with that, if you will try smth like


`$user->with('relation1.relation2.relation3');`
where `relation2` doesn't exist, it will load only `relation1` and the rest will be skipped, and no exceptions/errors would be thrown.

Just don't forget to make all models then extend from that new abstract class.

【讨论】:

【参考方案2】:

我在所有 Laravel 项目中所做的是创建一个扩展 Eloquent Model 的 Model 类,并且我的所有模型都将扩展我的 Model 类,因此我可以使用我的规则覆盖 Eloquent Model 中的一些方法。

因此,您可以创建一个新类(我称之为模型)并使用 try/catch 块重新调整 null 来覆盖该方法,以防该异常由 eloquent 模型引发。

例子:

namespace App;

use Illuminate\Database\Eloquent\Model as EloquentModel;
use Illuminate\Database\Eloquent\RelationNotFoundException;

abstract class Model extends EloquentModel

    public static function with($relations)
    
        try 
            return parent::with($relations);
         catch (RelationNotFoundException $e) 
            return null;
        
    

【讨论】:

以上是关于为 Laravel 关系返回 null 而不是“调用未定义的关系”错误的主要内容,如果未能解决你的问题,请参考以下文章

当表 laravel 5.8 中没有数据时,null 返回总和而不是 0

Laravel 关系返回 null

laravel 雄辩的关系一对多返回 null

Laravel 多态关系返回 null

Laravel 一对多关系返回 null

Laravel - 将 Select2 默认设置为 NULL 而不是第一个选项