不存在的模型类的雄辩关系

时间:2014-12-13 15:43:51

标签: laravel eloquent laravel-5

我想在我的应用程序中有许多模型/模块,但有些客户端会删除其中一些模型/模块。

现在我有这样的关系:

public function people()
{
    return $this->hasMany('People', 'model_id');
}

当我运行$model = Model::with('people')->get();时,它运行正常

但如果People模型不存在怎么办?

目前我得到了:

  

ClassLoader.php第386行中的1/1 ErrorException:include(...):失败   打开流:没有这样的文件或目录

我试过

public function people()
{ 
    try {
       return $this->hasMany('People', 'model_id');
    }
    catch (FatalErrorException $e) {
        return null;
    }
}

或与:

public function people()
{ 
    return null; // here I could add checking if there is a Model class and if not return null
}

但使用此类方法$model = Model::with('people')->get();时无法正常工作。

我将有几十个关系,我不能在with中使用它们的列表。最好的方法是使用一些empty relation(返回null)只是为了使Eloquent不做任何事情,但在这种情况下,Eloquent仍然试图让它工作,我会得到:

  哎呀,好像出了什么问题。   Builder.php第430行中的1/1 FatalErrorException:调用成员函数   addEagerConstraints()on null

有没有简单的解决方案?

1 个答案:

答案 0 :(得分:7)

我能想出的唯一解决方案是创建自己的Eloquent\Builder类。

我称之为MyBuilder。让我们首先确保它实际使用。在您的模型中(最好是基本模型)添加此newEloquentBuilder方法:

public function newEloquentBuilder($query)
{
    return new MyBuilder($query);
}

在自定义Builder课程中,我们会覆盖loadRelation方法,并在关系调用if null之前添加addEagerConstraints检查(或者在{ {1}})

null

该函数的其余部分基本上与原始构建器(class MyBuilder extends \Illuminate\Database\Eloquent\Builder { protected function loadRelation(array $models, $name, Closure $constraints) { $relation = $this->getRelation($name); if($relation == null){ return $models; } $relation->addEagerConstraints($models); call_user_func($constraints, $relation); $models = $relation->initRelation($models, $name); $results = $relation->getEager(); return $relation->match($models, $results, $name); } }

中的代码完全相同

现在只需在你的关系函数中添加这样的东西,它应该都可以工作:

Illuminate\Database\Eloquent\Builder

更新:使用喜欢关系

如果你想像关系一样使用它,它会变得有点棘手。

您必须覆盖public function people() { if(!class_exist('People')){ return null; } return $this->hasMany('People', 'model_id'); } 中的getRelationshipFromMethod功能。所以让我们创建一个基础模型(你的模型显然需要扩展它......)

Eloquent\Model

现在我们需要修改关系以返回空集合

class BaseModel extends \Illuminate\Database\Eloquent\Model {
    protected function getRelationshipFromMethod($key, $camelKey)
    {
        $relations = $this->$camelKey();

        if ( $relations instanceof \Illuminate\Database\Eloquent\Collection){
            // "fake" relationship
            return $this->relations[$key] = $relations;
        }
        if ( ! $relations instanceof Relation)
        {
            throw new LogicException('Relationship method must return an object of type '
                . 'Illuminate\Database\Eloquent\Relations\Relation');
        }

        return $this->relations[$key] = $relations->getResults();
    }
}

更改public function people() { if(!class_exist('People')){ return new \Illuminate\Database\Eloquent\Collection(); } return $this->hasMany('People', 'model_id'); } 中的loadRelation功能以检查类型集合而不是MyBuilder

null