![](/img/trans.png)
[英]Call to a member function addEagerConstraints() on null
[英]Call to a member function addEagerConstraints() on null because of a conditional relationship
我必须处理具有次优数据库设计的 Laravel 7 应用程序,导致标题中提到的错误。
数据库看起来像这样:
mains
- id
- sub_type
subs_a
- id
- main_id
subs_b
- id
- main_id
然后我有一个带有方法sub
的类Main
:
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
实例,然后尝试加载关系。 这不起作用,因为方法sub
的默认值是null
。
重构数据库在待办事项列表中,但目前这没有任何帮助。
我有什么选项可以阻止 Laravel 尝试在空对象上加载sub
关系?
我知道这是某种预期,但试图返回一个空的关系?
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 上的错误。
我想指出的几件事是,您的关系不应该是有条件的,在创建您想要的默认关系之后,您可以定义范围并管理内容或使用withDefault在失败的情况下返回一些内容。
关于在 null 上调用成员函数的错误:- 下面是另一个例子
<?php
class 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救援帮助函数中,您可以选择使用。
<?php
class 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 而不是 object,因此根据您在使用它时的纪律,您可以做出决定。
我想怎么处理你的情况?
异常类
<?php
namespace App\Exceptions;
use Exception;
class SubTypeNotFound extends Exception {
public function report()
{
\Log::debug('Could not find this subtype');
}
}
?>
模型类
<?php
class 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()
{
if($this->sub_type){
switch($this->sub_type) {
case 'a':
return $this->hasOne('SubTypeA');
break;
case 'b':
return $this->hasOne('SubTypeB');
break;
default:
return null;
}
}else{
return null
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.