猿问

由于条件关系而对 null 调用成员函数 addEagerConstraints()

我必须处理一个 Laravel 7 应用程序,该应用程序的数据库设计不理想,导致标题中提到的错误。


数据库看起来像这样:


mains

- id

- sub_type


subs_a

- id

- main_id


subs_b

- id

- main_id

然后我有一个Main带有方法的类sub:


public function sub()

{

    switch($this->sub_type) {

        case 'a':

            return $this->hasOne('SubTypeA');

            break;

        case 'b':

            return $this->hasOne('SubTypeB');

            break;

        default:

            return null;

    }

}

此代码适用于 99% 的情况,但 Laravel 有时会加载 的空实例Main,然后尝试加载关系。这是行不通的,因为 method 的默认值sub是null.


重组数据库已列入待办事项列表,但目前没有任何帮助。


我需要什么选项来阻止 Laravel 尝试sub在空对象上加载关系?


慕莱坞森
浏览 113回答 3
3回答

繁星coding

我知道这是某种预期,但尝试返回一个空关系?public function sub(){    switch($this->sub_type) {        case 'a':            return $this->hasOne('SubTypeA');            break;        case 'b':            return $this->hasOne('SubTypeB');            break;        default:            return $this->newQuery();  // or newQueryWithoutScopes()    }}它应该防止 addEagerConstraints() 对 null 的错误。

12345678_0001

我想指出的几件事是,您的关系不应该是有条件的,在将默认关系设置为您想要的默认关系之后,您可以定义范围并管理内容或使用withDefault在失败情况下返回某些内容。关于在 null 上调用成员函数的错误:- 下面是另一个示例<?phpclass MyClass{    function bar(){        echo "something";    }}class MyAnotherClass{    function foo(){        if (1>2) {            $obj = new MyClass();            $obj->x = $x;            $obj->y = $y;            $obj->save();            return $obj;        } else {            return null;        }    }}$myAnotherObj = new MyAnotherClass();$myClass = $myAnotherObj->foo();$myClass->bar()?>与其这样做,我更愿意抛出异常并处理它,这样我就能得到失败的具体原因,在 Laravel救援辅助函数中你可以选择使用。<?phpclass MyClass{    function bar(){        echo "something";    }}class MyAnotherClass{    function foo(){        if (1>2) {            $obj = new MyClass();            $obj->x = $x;            $obj->y = $y;            $obj->save();            return $obj;        } else {            throw new Exception("could not create my class object", 100); // Better to create custom exception class here        }    }}$myAnotherObj = new MyAnotherClass();try {    $myClass = $myAnotherObj->foo();    $myClass->bar();} catch(Exception $e) {    echo $e->getMessage();}?>如果对我来说数据不是那么重要我会考虑创建一个空对象<?php    class MyClass{        function bar(){            echo "something";        }    }        class MyAnotherClass{        function foo(){            $obj = new MyClass();            if (1>2) {                $obj->x = $x;                $obj->y = $y;                $obj->save();              }             return $obj;        }    }        $myAnotherObj = new MyAnotherClass();    $myClass = $myAnotherObj->foo();    $myClass->bar()  ?>但是如果您正在使用该对象属性进行操作,那么属性将为 null 而不是对象,因此根据您在使用它时的纪律,您可以做出决定。我想如何处理你的情况?异常类<?phpnamespace App\Exceptions;use Exception;class SubTypeNotFound extends Exception {    public function report()    {        \Log::debug('Could not find this subtype');    }}?>模型类<?phpclass Mains extends Model{    public function subA()    {        return $this->hasOne(SubTypeA::class);    }        public function subB()    {        return $this->hasOne(SubTypeB::class);    }    public function scopeSub($query, $type)    {        return $query          ->when($type === 'a',function($q){              return $q->with('subA');         })         ->when($type === 'b',function($q){              return $q->with('subB');         }),function($q){             throw SubTypeNotFound();         });    }}?>检索它时try {    $sub = Mains::sub('a')->get();} catch(SubTypeNotFound $e) {    return $e->getMessage();}如果有,$this->sub_type您可以避免使用该type参数。

慕沐林林

您可以简单地将 if 条件放在 switch case 之前。public function sub(){&nbsp; &nbsp; if($this->sub_type){&nbsp; &nbsp; &nbsp; &nbsp; switch($this->sub_type) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'a':&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return $this->hasOne('SubTypeA');&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'b':&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return $this->hasOne('SubTypeB');&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }else{&nbsp; &nbsp; &nbsp; &nbsp; return null&nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp;}
随时随地看视频慕课网APP
我要回答