我有一个模型,我们叫它Parent
。
每个Parent
可以有多个孩子。
public function children(): HasMany
{
return $this->hasMany(Child::class, 'parent_id', 'id');
}
我想为Parent
创建一个名为"active"的作用域。
我的要求如下:
父节点至少有1个子节点时是活动的。
我已经做了多次局部作用域,我知道在Parent.php
中我可以做这样的事情:
public function scopeActive($query)
{
return $query->where(…);
}
但如你所见,$query
是IlluminateDatabaseEloquentBuilder
,这不是我的情况。我想对相关模型进行操作,而不是数据库查询。
我能做到这一点,在一个干净的方式没有抓取所有的父with('child')
和->filter()
内忘记那些没有孩子?当有1000个父母,但只有一个会有孩子,它会简单地浪费DB资源(通过获取999个冗余的父母)。
您可以使用以下查询
public function scopeActive($query)
{
return $query->has('children');
}
一个选择是在作用域内使用whereHas
:
public function scopeActive($query){
return $query->whereHas('children');
}
或
public function scopeActive(){
return $this->whereHas('children');
}
和
Parent::active()->with('children')->get();
应该给你所有有孩子的父母和各自的孩子
你能不能试试这样写:
public function getActiveAttribute() {
return $this->children()->count() > 1;
}
可以这样使用,
$parent->active
查询只会在您尝试访问Parent
模型上的active
属性时进行,而不是在您将获取所有父级时进行。
In Parent
public function getActiveAttribute() {
return $this-> children()->exists();
}
在代码中
$parent = new Parent;
if($parent->active){//true}
也可以使用count
count ($ this→孩子);//0求值为false
如果你需要的话,这里有一个相关的线程:Laravel检查相关模型是否存在