我正在使用Laravel Framework 5.6.17
。我有2个模型通过many to many与数据透视表链接。
相关模型Question
和Tag
与tag_question
表相关联。
问题可以包含许多标签,标签可以包含许多问题。
模型看起来像这样:
class Question extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'title', 'body',
];
/**
* @var bool
*/
public $timestamps = true;
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function tags()
{
return $this->belongsToMany(Tag::class, 'tag_question');
}
}
class CreateQuestionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('questions', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->longText('body');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('questions');
}
}
class Tag extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'tag',
];
/**
* @var bool
*/
public $timestamps = true;
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function questions()
{
return $this->belongsToMany(Question::class, 'tag_question');
}
}
class CreateTagsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->string('tag');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('tags');
}
}
枢轴看起来像这样:
class CreateTagQuestionTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tag_question', function (Blueprint $table) {
$table->increments('id');
$table->integer('question_id');
$table->integer('tag_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('tag_question');
}
}
没有什么不寻常的,相当直接的东西。
问题
我尝试按标签过滤问题,并且我使用以下查询执行此操作:
$q = $question
->with(['tags' => function($query) use($request) {
$query->where('tags.tag', '=', $request->query('tag'));
}])
->orderBy('created_at', 'DESC')
->paginate(10);
但是,所有问题都会被检索到,无论他们拥有什么标签,或者他们是否有任何标签(标签不是强制性的,尽管这不重要)。
请注意,我没有收到错误,一切正常,除非它检索到意外结果。
到目前为止我尝试了什么
几乎我能想到的任何事情。
运行的查询如下:
select * from `users` where `id` = '1' limit 1
select count(*) as aggregate from `questions`
select * from `questions` order by `created_at` desc limit 10 offset 0
select `tags`.*, `tag_question`.`question_id` as `pivot_question_id`, `tag_question`.`tag_id` as `pivot_tag_id` from `tags` inner join `tag_question` on `tags`.`id` = `tag_question`.`tag_id` where `tag_question`.`question_id` in ('1', '2', '3', '4', '5', '52', '53', '54', '55', '56') and `tag` = 'test'
答案 0 :(得分:3)
您需要使用->whereHas()
代替with()
:
$q = $question
->whereHas('tags', function($query) use($request) {
$query->where('tags.tag', '=', $request->query('tag'));
})
->orderBy('created_at', 'DESC')
->paginate(10);
但是,这不会急于加载标签。因此,如果您还希望加载标记,则仍需要添加->with('tags')
。