Autocomplete and popular tags
Autocomplete
// Slug-prefix matches in every supported locale first, then names containing the term, each by usage
Tags::type('label')->suggest('liv'); // Live, Liverpool… — then names containing liv
Tags::type('label')->suggest('liv', limit: 5); // at most tags.suggest.max_limit
Tags::type('label')->within($team)->suggest('pri'); // the team's tags and the global onesPopular tags
use Illuminate\Database\Eloquent\Builder;
// By the cached usage count — every taggable class, soft-deleted taggables included
Tags::type('label')->popular(); // tags.popular.limit
Tags::type('label')->popular(20);
// Live, on one taggable class — and only on the records you may show
Tags::type('label')->popular(on: Concert::class);
Tags::type('label')->popular(10, on: Concert::class, where: fn (Builder $concerts) => $concerts->where('listed', true));
// The live count is on each returned tag
Tags::type('label')->popular(on: Concert::class)->first()?->taggables_count;| Call | Meaning |
|---|---|
suggest($term, $limit) | Tags whose slug in any supported locale starts with the term’s slug, then — only while there is room — tags whose name contains the term; each phase by usage count. A term that normalises to nothing returns an empty collection. |
popular($limit) | By the cached usage_count: every taggable class, soft-deleted taggables included. Unused tags are left out. |
popular($limit, on: Concert::class) | A live count of that class’s taggings, as taggables_count on each tag. |
popular($limit, on: …, where: fn (Builder $q) => …) | The live count restricted to the records you may show — a tag used only on hidden records neither counts nor appears. where without on throws InvalidArgumentException. |
Both read the handle’s scopes: within($team) suggests and ranks the team’s tags plus the global ones. Limits are clamped between 1 and tags.suggest.max_limit or tags.popular.max_limit.
Usage counts
usage_count is adjusted in the same transaction as every tagging write, under the tag row’s lock, so it stays exact under concurrent writers. It counts every taggable class and keeps soft-deleted taggables, and a deleted tag’s count drops to zero with its taggings. Recount with tags:repair --counts after writes past the package (a raw SQL import); after a mass delete of taggables, tags:repair --orphans removes the leftover taggings and recounts the tags they pointed at.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.