Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Taggable Laravel Package

mmanos/laravel-taggable

mmanos/laravel-taggable is a Laravel package for adding reusable tags to Eloquent models. Its taggable trait provides polymorphic tag relationships and helpers to tag, untag, retag, and query models by tag, plus scopes for filtering, making tag management simple across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

The package ships a custom Eloquent query builder that overrides the parent builder's first() method so it resolves from a collection instead of issuing a fresh SELECT ... LIMIT 1. In practice that means the "first record" can come from data you already hydrated (a get() result, a cached payload, an eager-loaded relation set) rather than a new round-trip to the database.

Minimal steps to get productive:

  1. composer require <vendor>/<package> — check the resolved version. v1.0.1 is the release that introduces the first() override, so anything pinned at 1.0.0 will behave differently.
  2. Find the builder class — it is the one extending Illuminate\Database\Eloquent\Builder and reimplementing first(). That single method is the entire surface area of this release; read it before anything else.
  3. Find how models opt in: usually via an overridden newEloquentBuilder() on the model, a trait, or a base model the package expects you to extend. If there is a config file or service provider, publish it and confirm whether the behaviour is global or per-model.
  4. Check whether there is a first() test in the package's suite that demonstrates the intended collection source. That test is your de-facto spec.

First use case to try: a read endpoint that already does Model::where(...)->get() for a list view and then calls ->first() on the same result. In v1.0.1 that second call should be free — verify it with DB::listen() and count the queries.

Implementation Patterns

Load-once-then-first. The intended shape is: build the query, get() the collection, and derive the head of that collection rather than issuing a second query. Good fit for dashboards, "latest item" widgets, or any screen where the list and the highlighted record are the same data set.

Repository / cache layer. If you already return an Eloquent Collection from a cache or an in-memory store, ->first() becomes the natural accessor and stops being the one line in your repository that escapes the cache and hits the DB. This is where the override earns its keep.

Query-count assertions. Bake the guarantee into tests rather than trusting it:

DB::enableQueryLog();
$result = $query->get()->first();
$this->assertCount(1, DB::getQueryLog()); // only the get()

Keep the two paths separate. Have hot paths that need a collection-derived first explicitly go through the package builder, and leave first()-as-a-query on models/query builders that don't opt in. Blurring the two makes the next debugging session expensive.

Transformers and API resources. Collections handed to Resource::collection() plus a separate ->first() for a meta block is a clean pairing — one hydration, two consumers.

Scope the override. If the package lets you register the builder per model, apply it only to models whose read paths genuinely reuse collections. A global override turns every first() in the app into a semantic question mark.

Gotchas and Tips

  • firstOrFail() / sole() / value() interactions. These typically delegate to first() internally. If the override returns a collection-derived model, firstOrFail() may throw ModelNotFoundException for a row that exists in the database but wasn't in the loaded collection. Audit every derived method, not just first().
  • Constraints applied after hydration are silently dropped. ->where('active', 1)->first() will not filter the collection unless the override re-applies constraints. Filtering done on the builder after the collection exists is a no-op — and a silent one.
  • Ordering semantics shift. orderBy('created_at', 'desc')->first() returns "first in the loaded collection," which is whatever order get() produced. If you need DB-ordered head, sort the collection or don't use this path.
  • first($columns) ignores the column list in most collection-backed implementations, since the models are already fully hydrated. Don't rely on partial selects for memory savings here.
  • Staleness. Collection-sourced reads are by definition snapshots. In queue jobs, transactions, or long-running Octane workers, a first() that used to see fresh rows will now see cached ones. Pair with refresh()/load() where correctness matters.
  • Relations still need loading. A model returned from a collection has exactly the relations that were eager-loaded at get() time. first() doesn't fix N+1; loadMissing() still does. Keep Model::preventLazyLoading() on in non-production.
  • Semver surprise. This is a patch bump (1.0.0 → 1.0.1) that changes query behaviour. Treat it as behavioural, not cosmetic: pin 1.0.1 explicitly, and if you have query-count or assertDatabaseCount-style tests, run them before deploying.
  • Debugging. toSql() and getBindings() describe the underlying query, not what the override actually does. Reach for DB::listen() or DB::enableQueryLog() to confirm whether a query fired at all; add dump($builder->getQuery()) when you suspect constraints were discarded.
  • Extension points. Subclass the package builder if you need to align firstOrFail, sole, or re-apply pending wheres against the collection. Overriding newEloquentBuilder() on your own base model is the least invasive hook. Macros registered on the builder are unaffected by the override but can shadow it if named first.
  • Not covered by this release. find(), firstWhere(), cursor(), and pagination are untouched — don't assume the collection-first behaviour generalises across the builder API.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route