我能想到的唯一解决方案是创建你自己的Eloquent\Builder
class.
我已经这样称呼它了MyBuilder
。让我们首先确保它得到实际使用。在您的模型(最好是基本模型)中添加此newEloquentBuilder
method:
public function newEloquentBuilder($query)
{
return new MyBuilder($query);
}
在风俗中Builder
类我们将覆盖loadRelation
方法并添加一个if null
之前检查一下addEagerConstraints
被称为关系(或者在你的情况下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');
}
更新:使用它like一种关系
如果你想像处理人际关系一样使用它,那就有点棘手了。
你必须覆盖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
protected function loadRelation(array $models, $name, Closure $constraints)
{
$relation = $this->getRelation($name);
if($relation instanceof \Illuminate\Database\Eloquent\Collection){
return $models;
}
// ...
}