Laravel根据关系的值返回一个有说服力的值



我试图根据列的值从表返回数据。让我解释一下。

我有3张表。books,genres和一个数据透视表来关联这两个表的值。

  1. books
  2. genres
  3. 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表中,我将genreactive属性更改为false,并且genrebook相关联,那么它不应该显示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财产genrefalse,它没有显示genere集合中,但如果book2genres,其中一个保持在trueactive地产,然后返回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);
});
}
}

最新更新