首页  >  问答  >  正文

按标签搜索帖子

我需要按标签显示帖子。我的解决方案适用于单个标签,如下所示:

路线:

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粉323050780P粉323050780179 天前444

全部回复(1)我来回复

  • P粉596161915

    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[]=...,如果未提供则为空数组。

    回复
    0
  • 取消回复