mgboateng/eloquent-slug
A Laravel package for automatic slug generation on Eloquent models. It helps create unique, URL-friendly slugs from chosen attributes, simplifying clean routes, SEO-friendly links, and manual slug handling in your application.
This package is still pre-1.0 (v0.2.0), so pin it explicitly in composer.json ("vendor/package": "0.2.*") rather than floating on ^0.1 — minor bumps before 1.0 are where breaking changes land.
composer require vendor/packagephp artisan vendor:publish --provider="Vendor\Package\PackageServiceProvider" — expect a config file and, given the package touches the database, one or more migrations.php artisan migrate against your local connection.php artisan config:clear if you had a cached config from a previous install.Where to look first: the published config file (it tells you which connection/driver the package assumes), then the package's own migrations (they reveal the column types the v0.2.0 compatibility fix was about — json, uuid, boolean, and timestamp precision are the usual suspects). The service provider's register()/boot() shows what's bound into the container and what's publishable.
First use case: run the package's migrations and a basic write/read in a test on SQLite, then point the same code at MySQL or Postgres. Because v0.2.0 is specifically a cross-database compatibility fix, verifying parity across two drivers is the fastest way to confirm you are on a version that actually works for your stack — and to catch anything the fix didn't cover.
Resolve from the container, not the facade. If the package binds an interface (repositories, a manager class, a driver resolver), type-hint the interface in constructors and let Laravel inject it. This keeps your code testable and lets you swap the binding in a service provider for fakes.
Stay on the query builder / Eloquent, not raw SQL. The whole point of the v0.2.0 release is driver portability. Hand-written SQL in your own code — DATE_FORMAT, ILIKE, GROUP_CONCAT, INSERT ... ON DUPLICATE KEY — reintroduces exactly the incompatibility the package just fixed. If you must drop to raw SQL, gate it on DB::connection()->getDriverName().
Be explicit about connections. In multi-connection apps, pass the connection name (on('reporting'), ->connection('...')) rather than relying on the default. Packages that wrap a connection often accept one via config; use it, otherwise queue workers and console commands can silently hit a different database than your HTTP requests.
Wrap multi-step writes in transactions and use afterCommit for side effects. If the package dispatches events or jobs from within a write, add ->afterCommit() on the dispatch (or DB::afterCommit()) so a queued listener never sees a row the transaction later rolls back.
Test against more than SQLite. Use RefreshDatabase and add a CI matrix over the drivers you actually deploy — SQLite for speed, MySQL/Postgres for truth. A green suite on SQLite alone is precisely how a compatibility bug survives to a release.
Migrations are integration points. If you publish the package's migrations, copy them into your app rather than editing in vendor/. Once published, they're yours to modify — but you also own keeping them in sync when the package ships schema changes.
php artisan migrate will not alter an already-migrated table. If the package's migrations were published in v0.1.x, diff them against v0.2.0 and write an explicit follow-up migration. Test the upgrade path on a copy of real data, not a fresh database.integer vs bigint, boolean casts) and folds unquoted identifiers to lowercase; MySQL has index-length limits on utf8mb4; SQLite ignores column types and length constraints entirely, so it happily accepts data production will reject.ONLY_FULL_GROUP_BY. Queries that pass locally with MySQL strict mode off will fail in production. Keep strict => true in config/database.php in every environment.php artisan config:cache must be re-run. A stale cached config is the single most common "the package ignores my settings" cause.DB::listen(fn ($q) => logger($q->sql, $q->bindings)) in a service provider, or DB::enableQueryLog(), shows exactly what the package emits. Check DB::connection()->getDriverName() when behaviour diverges by environment — it's usually the driver, not the package.Macroable/custom-driver hooks are the sanctioned ways to extend. Prefer rebinding an interface over subclassing internals — internals churn between 0.x releases.How can I help you explore Laravel packages today?