I tried to fetching posts by tags. Tags have slugs, and tag link should lead to the page with tag slug in url. But I have problem with displaying posts with relevant tag on that page.
PostController. Method 'index' works well, displaying all posts with related tags. In 'fetch' method I tried to get slug for using it in function 'withAnyTag', as written in the documentation — https://github.com/rtconner/laravel-tagging/
public function index()
{
$posts = Post::orderBy('created_at', 'desc')->paginate(5);
return view('backend.post.index', compact('posts'));
}
public function fetch(Tag $tag)
{
$slug = $tag->slug;
$posts = Post::withAnyTag([$slug])->get()->paginate(5);
return view('backend.post.index', compact('posts'));
}
In Post model nothing specific, just trait Taggable.
Routes. I see no problem with them, bring it just in case.
Route::get('post', [PostController::class, 'index'])->name('posts');
Route::get('post/tag/{tag:slug}', [PostController::class, 'fetch'])->name('posts.fetch');
Fragment from view 'backend.post.index', using for both methods. Links work well and lead on the right url.
@foreach($posts as $post)
<tr>
<td>{!! $post->title !!}</td>
<td>{!! $post->content !!}</td>
<td>
@foreach($post->tags as $tag)
<a href="{{ route('posts.fetch', $tag->slug) }}">{!! $tag->name !!}</a>
@endforeach
</td>
<td>
<a href="/" class="btn btn-sm btn-outline-primary py-0">Read Post</a>
<a href="{{ route('post.edit', $post->slug) }}" class="btn btn-sm btn-outline-success py-0">Edit Post</a>
<form action="{{route('post.destroy', $post->slug)}}" method="POST">
@method('DELETE')
@csrf
<button type="submit" class="btn btn-sm btn-outline-danger py-0">Delete</button>
</form>
</td>
</tr>
@endforeach
{!! $posts->links() !!}
But, when I click on tag and get to the page '.../post/tag/tag-slug', appears an error 'Method Illuminate\Database\Eloquent\Collection::paginate does not exist.' In method 'index' was no mistake with pagination.
I think you should run paginate
directly on the withAnyTag
method like this
$posts = Post::withAnyTag([$slug])->paginate(5);
You don't need the separate call to get()
as paginate
will run the query and return a paginated result.