我想在我的应用程序中有许多模型/模块,但有些客户端会删除其中一些模型/模块。
现在我有这样的关系:
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
有没有简单的解决方案?
答案 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