雄辩的关系为不存在的模型类 [英] Eloquent relationships for not-existing model class

查看:206
本文介绍了雄辩的关系为不存在的模型类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



现在我有这样的关系:

  public function people() X-454545454545 X- 20045 X-454545 X-454545 X- 20045 X-454545 X- 20045 X-454545 X- 20045 X-4545 X- 20045 X-4545 
}

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



但是,如果 People

$ / $>

目前我正在获得:


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


< blockquote>

我尝试使用

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

或与:

  public function people()
{
return null; //这里我可以添加检查是否有一个模型类,如果不返回null
}

但是当使用这样的方法 $ model = Model :: with('people') - > get(); 不起作用



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


糟糕,看起来好像出了问题。
1/1 Builder.php中的FatalErrorException行430:调用成员函数
null上的addEagerConstraints()


有没有一个简单的解决方案?

解决方案

我可以想出的唯一解决方案是创建自己的 Eloquent\Builder class。



我已经调用它 MyBuilder 。我们首先确保它被实际使用。在你的模型(最好是基本模型)中,添加这个 newEloquentBuilder 方法:

  public function newEloquentBuilder($ query)
{
返回新的MyBuilder($ query);
}

在自定义 Builder class我们将覆盖 loadRelation 方法,如果null 之前添加一个 addEagerConstraints 被称为关系(或在您的情况下 null

  class MyBuilder extends \Illuminate\Database\Eloquent\Builder {
protected function loadRelation(array $ models,$ name,Closure $ constraints)
{
$ relation = $ this-> getRelation($ name);新评新新新新新旗新新新新旗新新旗新新旗新新旗新新旗新新旗新新旗新新旗新新旗新旗新旗新旗新旗新新旗新新旗新新旗名:
}


$ relation-> addEagerConstraints($ models);

call_user_func($ constraints,$ relation);新新新新旗新新新新旗新新旗新新旗新新旗新新旗新新新旗新新旗200新新新新旗新新旗200新新新新旗新新名:

$ results = $ relation-> getEager();

return $ relation-> match($ models,$ results,$ name);
}
}

其余功能基本上是相同的代码原始构建器( Illuminate\Database\Eloquent\Builder



现在只需添加如下所示你的关系函数应该都可以正常工作:

  public function people()
{
if(! class_exist('People')){
return null; X-454545454545 X- 20045 X- 20045 X-4545 X- 20045 X-4545 X- 20045 X-4545 X- 20045 X-4545 X- 20045 X- 20045 X- 20045 X- 20045 X-
}



更新:使用 h2>

如果你想使用它,就像你可以用一个关系,它有点更棘手。



你必须覆盖 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){
//假关系
返回$ this->关系[$ key] = $ relations;
}
if(!$ relations instanceof Relation)
{
throw new LogicException('关系方法必须返回一个类型为'
'的对象。照明\数据库\Eloquent\Relations\Relation');
}

返回$ this->关系[$ key] = $ relations-> getResults();
}
}

现在我们需要修改关系来返回一个空收集

  public function people()
{
if(!class_exist('People')){ X-45454545 X- 20045 X- 20045 X- 20045 X- 20045 X- 20045 X- 20045 X- 20045 X- 20045 X- 20045 X- 20045 X- 20045 X- X-454545454545 X- 20045 X- 20045 X-4545 X- 20045 X-4545 X- 20045 X-4545 X- 20045 X-4545 X- 20045 X- 20045 X- 20045 X- 20045 X-
}

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





$ relation = $ this-> getRelation($ name)
{
$ ;

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

// ...
}


I would like to have in my applications many models/modules but some of them would be removed for some clients.

Now I have such relation:

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

and when I run $model = Model::with('people')->get(); it is working fine

But what if the People model doesn't exist?

At the moment I'm getting:

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

I tried with

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

or with:

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

but when using such method $model = Model::with('people')->get(); doesn't work.

I will have a dozens of relations and I cannot have list of them to use in with. The best method for that would be using some empty relation (returning null) just to make Eloquent not to do anything but in this case Eloquent still tries to make it work and I will get:

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

Is there any simple solution for that?

解决方案

The only solution I could come up with is creating your own Eloquent\Builder class.

I've called it MyBuilder. Let's first make sure it gets actually used. In your model (preferably a Base Model) add this newEloquentBuilder method:

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

In the custom Builder class we will override the loadRelation method and add an if null check right before addEagerConstraints is called on the relation (or in your case on 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);
    }
}

The rest of the function is basically the identical code from the original builder (Illuminate\Database\Eloquent\Builder)

Now simply add something like this in your relation function and it should all work:

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

Update: Use it like a relationship

If you want to use it like you can with a relationship it gets a bit more tricky.

You have to override the getRelationshipFromMethod function in Eloquent\Model. So let's create a Base Model (Your model obviously needs to extend it then...)

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

Now we need to modify the relation to return an empty collection

public function people()
{
    if(!class_exist('People')){
        return new \Illuminate\Database\Eloquent\Collection();
    }
    return $this->hasMany('People', 'model_id');
}

And change the loadRelation function in MyBuilder to check for the type collection instead of null

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

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

    // ...
}

这篇关于雄辩的关系为不存在的模型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆