我需要按标签显示帖子。我的解决方案适用于单个标签,如下所示:
路线:
Route::get('/posts', [PostController::class, 'index'])->middleware('auth');
后模型过滤器:
public function scopeFilter($query, array $filters) { if ($filters['tag'] ?? false) { $tagId = Tag::where('name', $filters['tag'])->first()->id; $query->whereHas('tags', function($q) use ($tagId) { $q->where('tag_id', $tagId); }); } }
PostController 的方法索引:
public function index() { return view('posts', [ 'posts' => Post::latest()->filter(request(['tag']))->get() ]); }
此代码适用于如下网址:“http://127.0.0.1:8000/posts/?tag=test”。但我需要找到一种方法来搜索具有更多标签的帖子,例如我想查找带有“test”和“unit”标签的帖子。为此,我想使用如下网址:“http://127.0.0.1:8000/posts/?tag=test&unit”。我卡住了,因为我认为“request(['tag'])”将返回“test&unit”,但它只返回“test”。是否有可能以某种方式从此请求中获取“unit”标签?
P粉5961619152024-04-04 18:26:32
使用查询字符串的 GET
请求可以接受多个参数。而不是 ?tag=test&unit
(无论如何都不会真正起作用,因为 &unit
将被解析为 $request->input('unit')
,并且将是 null
,&
是保留字符),您可以发送为:
http://127.0.0.1:8000/posts?tags[]=test&tags[]=unit
在后端,当你访问 request()->input('tags')
时,你会得到以下数组:
$tags = request()->input('tags'); // ['test', 'unit']
所以,把它们放在一起:
// ScopeFilter method on your `Post` Model
public function scopeFilter($query, array $tagNames) {
if (!empty($tagNames)) {
$tagIds = Tag::whereIn('name', $tagNames)->pluck('id');
return $query->whereHas('tags', function($subQuery) use ($tagIds) {
return $subQuery->whereIn('tags.id', $tagIds);
});
// Alternative without `$tagIds`, using `$tagNames` directly
// return $query->whereHas('tags', function($subQuery) use ($tagNames) {
// return $subQuery->whereIn('tags.name', $tagNames);
// });
}
return $query;
}
// Usage
public function index() {
return view('posts', [
'posts' => Post::latest()->filter(request()->input('tags', []))->get()
]);
}
whereIn()
处理多个值request()->input('tags', [])
访问 ?tags[]=...&tags[]=...
,如果未提供则为空数组。