我正在开发一个系统,我可以在其中为一个字母分配标签。关系如下:
用户有多个邮箱
邮箱有很多信件,有一个用户
字母有多个标签和hasOne邮箱
标签有很多字母
现在我将所有标签存储在这样的会话中:
session()->push('tags', collect($tag->id));
然后我把它们放到一个数组中,这样我就可以在Tag模型上使用WhereIn,然后我通过标签来获取所有带有这些标签的字母,这就是问题的起点。我想过滤会话中所有标签上的字母。它目前一次过滤一个标签而不是所有标签。
代码如下:
$searchtags = array();
if(session()->get('tags')) {
foreach (session()->get('tags') as $tag) {
array_push($searchtags, $tag[0]);
}
$tags = \App\Tag::whereIn('id', array_values($searchtags))->with('letters')->get();
$letter_ids = array();
foreach($tags as $tag) {
foreach($tag->letters as $letter) {
array_push($letter_ids, $letter->id);
}
}
$letters = \App\Letter::whereIn('id', array_values($letter_ids))
->where('mailbox_id', '=', Auth::user()->activeMailboxId)
->orderBy('created_at', 'desc')
->where('service','send')
->paginate(8);
}
为了让事情更清楚,问题是:
如果一个字母的标签附有id为41的标签,而带有应该过滤的标签的Session变量包含id的41和42,它当前将返回附有标签ID 41的那个字母。但它应该没有回复,因为ID 42没有附在这封信上。
编辑:它应该像这个查询一样工作:
SELECT * FROM letters
INNER JOIN letter_tag ON letters.id = letter_tag.letter_id
INNER JOIN tags ON letter_tag.tag_id = tags.id
WHERE letter_tag.tag_id IN(51,52) AND letters.mailbox_id = 2353 AND letters.deleted_at IS NULL
HAVING COUNT(DISTINCT letter_tag.tag_id) = 2
除了将HAVING计数更改为1而将IN更改为仅51,它将返回正确的字母