gpt4 book ai didi

laravel - 不存在的模型类的 Eloquent 关系

转载 作者:行者123 更新时间:2023-12-02 07:26:48 24 4
gpt4 key购买 nike

我希望在我的应用程序中有许多模型/模块,但对于某些客户,其中一些会被删除。

现在我有这样的关系:

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

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

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

目前我得到:

1/1 ErrorException in ClassLoader.php line 386: include(...): failed to open stream: No such file or directory

我试过

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 中使用它们的列表。最好的方法是使用一些空关系(返回空值)只是为了让 Eloquent 不做任何事情,但在这种情况下 Eloquent 仍然试图让它工作,我会得到:

Whoops, looks like something went wrong. 1/1 FatalErrorException in Builder.php line 430: Call to a member function addEagerConstraints() on null

有什么简单的解决方案吗?

最佳答案

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

我将其命名为 MyBuilder。让我们首先确保它被实际使用。在您的模型(最好是基础模型)中添加此 newEloquentBuilder 方法:

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

在自定义 Builder 类中,我们将覆盖 loadRelation 方法并在 addEagerConstraints 之前添加一个 if null 检查> 在关系上被调用(或者在你的情况下在 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');
}

更新:一段关系一样使用它

如果你想像处理关系一样使用它,那就有点棘手了。

您必须覆盖 Eloquent\Model 中的 getRelationshipFromMethod 函数。所以让我们创建一个基础模型(你的模型显然需要扩展它......)

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');
}

并更改 MyBuilder 中的 loadRelation 函数以检查类型集合而不是 null

protected function loadRelation(array $models, $name, Closure $constraints)
{
$relation = $this->getRelation($name);

if($relation instanceof \Illuminate\Database\Eloquent\Collection){
return $models;
}

// ...
}

关于laravel - 不存在的模型类的 Eloquent 关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27460614/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com