Php 如果列值为NULL或0,则不要运行关系查询
在我的Php 如果列值为NULL或0,则不要运行关系查询,php,mysql,laravel,eloquent,Php,Mysql,Laravel,Eloquent,在我的雄辩的模型中,我有各种各样的关系,看起来像这样: public function main_image() { return $this->hasOne(Media::class, 'id', 'main_image_id'); } select * from `media` where `media`.`id` is null and `media`.`id` is not null limit 1 但是,如果main\u image\u id为null或0,它将运行一
雄辩的模型中,我有各种各样的关系,看起来像这样:
public function main_image()
{
return $this->hasOne(Media::class, 'id', 'main_image_id');
}
select * from `media` where `media`.`id` is null and `media`.`id` is not null limit 1
但是,如果main\u image\u id
为null或0,它将运行一个SQL查询,因此我最终得到了如下一些查询:
public function main_image()
{
return $this->hasOne(Media::class, 'id', 'main_image_id');
}
select * from `media` where `media`.`id` is null and `media`.`id` is not null limit 1
这显然不会返回任何东西,但仍然浪费资源。有没有办法自动检查
目前我所做的是有一个方法,比如hasMainImage()
,它检查main\u image\u id
是否为空且不为0,但是当前的许多系统已经使用了关系,我想知道是否可以将检查添加到关系方法本身
我已经尝试向它添加一个检查,如果列没有实际值,则返回null
,但是我得到了一个异常
,它必须返回一个关系对象。或者,如果我试图加载它,我会收到以下错误:
在null上调用成员函数addagerConstraints()
public function main_image()
{
if (!$this->main_image_id) {
return null;
}
return $this->hasOne('App\Modules\Media\Models\Media', 'id', 'main_image_id');
}
谢谢你的帮助
编辑:
一个也许更清楚的例子:
$page = Page::find(1);
var_dump($page->main_image); // This will run a query as shown above that is guaranteed to return nothing
// Since at this point system knows that $page->main_image_id is 0 or null, I would like to use that to not run the query and automatically set $page->main_image to null
你以错误的顺序宣布你的关系,这一点很清楚
本身没有意义的实体(你可以说没有它的“父对象”)应该包含“belongsTo”关系(正如文档所说的相反)
为了演示,让我们假设您有用户模型,并且您有关于该用户的许多详细信息,所以您可以创建详细模型
现在,用户模型应具有详细关系:
public function detail() {
return $this->hasOne('App\Detail', 'user_id', 'id'); //you can see the difference here from your code sample, you have 2nd and 3rd parameter reversed
}
public function user()
{
return $this->belongsTo('App\User');
}
详细模型应具有用户关系:
public function detail() {
return $this->hasOne('App\Detail', 'user_id', 'id'); //you can see the difference here from your code sample, you have 2nd and 3rd parameter reversed
}
public function user()
{
return $this->belongsTo('App\User');
}
使用
执行操作会使用额外的资源。你不应该一开始就这样做,不要在任何地方都这样做,然后尝试绕过它。with
不是在任何地方都使用,只是在同时加载多个模型的情况下。当仅加载单个实例时,不使用带的,,并调用$page->main\u image
。这些都是我试图优化的,如果你这样做,没有额外的好处。连接将以任何方式发生,它只会返回较少的内容。当然,我假设您在这里有一对一的关系。我的目标不是运行SQL查询,当我在执行像$page->main\u image
这样的调用时,我知道$page->main\u image\u id
是0
或null
。我需要在模型的方法级别进行检查。如果您渴望加载,那么$page->main_image
不会/不应该触发单个查询。查询是在整个结果集上预先完成的。这不是我目前拥有的结构。我有页面
模型和媒体
模型<代码>媒体
模型是一个自包含的模型,不附加到任何其他模型(因为它可以被不同的模型和模型实例多次使用)<代码>页面
有一个主图像
方法(在任务中定义),该方法定义了与媒体的关系
。如果我事先知道SQL查询不会返回任何内容,那么我不想运行SQL查询。我不确定在媒体
模型中定义belongsTo
如何解决这个问题?我不需要以任何方式从媒体
实例中访问任何其他模型。在这种情况下不需要页面
模型可以有一个媒体
作为主图像
与之相关,但是,相同的媒体
模型可以作为主图像
与其他页面相关,许多其他模型作为不同类型的图像。因此,Page
“有一个”媒体对象,它在Page
表中作为main\u image\u id
引用。我想知道我是否应该在这里使用belongsTo
关系?这是否会对运行查询产生影响?我假设它将运行我想以任何一种方式消除的SQL查询,因为其中可能有一个0。我现在理解你关于错误顺序的意思。但是,我已将hasOne
切换到belongsTo
,这对我在这里试图解决的查询和问题没有任何影响。@Giedrius演示如何访问所讨论的实体。@Giedrius嘿,好消息是监视PR,如果它被合并,您可以使用->with default()
并设置“空”关系,不确定它是否会出现在桌面上,但它会帮助你的情况。