繁体   English   中英

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

[英]Returning null instead of "Call to undefined relationship" error for Laravel relationships

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

但是对于多态关系,我得到了所有相关模型的集合,我想使用with('somerelation')并在未定义关系时获取null 有什么方法可以避免错误并从 with() 或有条件地使用 with 返回 null 吗?

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

因此,您可以创建一个新类(我称其为 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;
        }
    }
}

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

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

唯一的事情是该方法的代码应该如下所示:

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.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM