【问题标题】:Returning null instead of "Call to undefined relationship" error for Laravel relationships为 Laravel 关系返回 null 而不是“调用未定义的关系”错误
【发布时间】: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 的方法?

【问题讨论】:

    标签: php laravel eloquent


    【解决方案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;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2014-08-21
        • 2020-01-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多