我试图根据列的值从表返回数据。让我解释一下。
我有3张表。books
,genres
和一个数据透视表来关联这两个表的值。
表
books
genres
book_genre
存在many-to-many
关系,因为book
可以包含不同的genres
,genre
可以关联不同的books
。
关系
Book Model
class Book extends Model
{
use HasFactory;
/**
* @inheritdoc
*
* @var string[]
*/
protected $fillable = [
'title',
'language',
'thumbnail',
'active'
];
/**
* @inheritdoc
*
* @return void
*/
protected static function boot()
{
parent::boot();
static::addGlobalScope(new ExcludeBookWhenInactiveRelations());
}
/**
* Genders relationship
*
* @return BelongsToMany
*/
public function genres()
{
return $this->belongsToMany(Genre::class);
}
}
Genre Model
class Genre extends Model
{
use HasFactory;
/**
* @inheritdoc
*
* @var string[]
*/
protected $fillable = [
'name',
'active'
];
/**
* Books relationship
*
* @return BelongsToMany
*/
public function books()
{
return $this->belongsToMany(Book::class);
}
}
现在,我试图在我的Book
模型中创建global scope
,因此在查询时,它只返回books
,其genres
尚未被禁用。也就是说,如果在我的genre
表中,我将genre
的active
属性更改为false,并且genre
与book
相关联,那么它不应该显示book
.
这是我正在创建的Global Scope
:
class ExcludeBookWhenInactiveRelations implements Scope
{
/**
* @inheritdoc
*
* @param Builder $builder
* @param Model $model
* @return Builder|void
*/
public function apply(Builder $builder, Model $model)
{
return $builder->whereHas('genres', function ($query) {
return $query->where('active', true);
});
}
}
所发生的是,当我改变的值active
财产genre
false
,它没有显示genere
集合中,但如果book
2genres
,其中一个保持在true
active
地产,然后返回book
跟着我,和我想做的是如果book
至少1gender
残疾(false)
,然后它不显示在收藏。
您的雄辩设置正在创建此查询。
select * from books where exists (select * from genres inner join book_genre on genres.id = book_genre.genre_id where books.id = book_genre.book_id and active = 1)
这里的如果书只有一种活动体裁,它将被选中。这是错误的。现在您需要另一个没有太大区别的查询。
select * from books where not exists (select * from genres inner join book_genre on genres.id = book_genre.genre_id where books.id = book_genre.book_id and active = 0)
如果book只有一个未激活的类型,它将从最终记录中取消选择。
@leo95batista雄辩地提供了这个查询。
class ExcludeBookWhenInactiveRelation implements Scope
{
/**
* @inheritdoc
*
* @param Builder $builder
* @param Model $model
* @return Builder|void
*/
public function apply(Builder $builder, Model $model)
{
return $builder->whereDoesntHave('genres', function (Builder $query) {
return $query->where('active', false);
});
}
}