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 Db Rebuild Laravel Package

webparking/laravel-db-rebuild

A Laravel package that adds a db:rebuild Artisan command to quickly reset your database by dropping all tables, rerunning migrations, and optionally seeding. Ideal for local development and testing, it makes repeatable database refreshes fast, consistent, and simple without manual SQL.

View on GitHub
Deep Wiki
Context7

Getting Started

Install with Composer and let Laravel's package auto-discovery wire it up:

composer require webparking/laravel-db-rebuild --dev

On Laravel 5.5+ the service provider is discovered automatically via extra.laravel.providers in the package's composer.json. If you are on an older framework version or have discovery disabled, register Webparking\DbRebuild\DbRebuildServiceProvider manually in config/app.php.

Where to look first. After install, run:

php artisan list | grep -i rebuild

That prints the exact command signature this version exposes (typically db:rebuild), its options, and its description. Read the command class itself under vendor/webparking/laravel-db-rebuild/src/Commands/ — the implementation is small, and confirming exactly which options exist (--seed, --class, --connection, --force) is faster than guessing from the README.

First use case. Point it at your local development database and verify the destructive behaviour before you trust it:

# Confirm which connection and database you are pointed at
php artisan db:show   # or your tinker / .env check

# First run: no seeding, just drop + migrate
php artisan db:rebuild

Success looks like: all tables dropped, every migration in database/migrations/ replayed from scratch, and an empty schema matching php artisan migrate:fresh output. Once that is green, add seeding:

php artisan db:rebuild --seed

If either run surprises you — wrong connection hit, tables you did not expect to be dropped — stop and read the Gotchas section before using it in CI.

Implementation Patterns

Daily local reset loop. The canonical workflow is "pull main, reset to a known schema, seed, start working":

git pull && composer install && php artisan db:rebuild --seed

Wire it into a Composer script so every developer runs the same thing:

"scripts": {
    "db:reset": [
        "@php artisan db:rebuild --seed"
    ]
}

Then composer db:reset. This is the single highest-value integration — it collapses a multi-step migrate:rollback/migrate:fresh/db:seed dance into one memorable command and removes the "it works on my machine, my migrations are out of order" class of bug.

CI pipeline step. In CI you want a deterministic database before the test suite runs. Two common shapes:

# Option A: rebuild before the suite, no seeding
- run: php artisan db:rebuild

# Option B: rebuild with a minimal seeder for integration tests
- run: php artisan db:rebuild --seed --class=Database\\Seeders\\CiSeeder

Option A pairs well with a test trait (RefreshDatabase or DatabaseTransactions) that handles per-test isolation; the rebuild is only there to guarantee the schema exists and migrations apply cleanly on a fresh database — which catches migration ordering bugs that a developer's long-lived local DB silently hides. Option B is useful for smoke/e2e tests that assert against seeded reference data. Keep the CI seeder a dedicated class: never reuse DatabaseSeeder if it contains demo data or slow fixtures.

Seed strategy per environment. Define seeders that match intent, not environment:

Context Seeder Why
Local dev DatabaseSeeder Full demo dataset: users, sample orders, images
CI / test Minimal seeder (e.g. CiSeeder) Only reference/lookup rows required for assertions
Demo / staging DemoSeeder Realistic-but-fake volume for click-through

Pass the class explicitly: --class=Database\\Seeders\\CiSeeder. This keeps DatabaseSeeder free to call slower or faker-heavy seeders without CI paying the cost.

Targeting a non-default connection. If your app has multiple connections (mysql, pgsql, testing), pass --connection=... rather than mutating DB_CONNECTION in the shell. Explicit is safer, especially when the command drops tables — you want that target visible in the invocation line, not buried in an env override:

php artisan db:rebuild --connection=pgsql --seed

Paired with migrate:fresh for comparison. migrate:fresh drops all tables and re-runs migrations; db:rebuild provides the same outcome plus an optional seeder in one command. Adopt db:rebuild as the canonical reset and use migrate:fresh only when you specifically need --step/--path behaviours that the rebuild command does not expose.

Guardrails in application code. Because this command is irreversibly destructive, add belt-and-braces at the application layer:

  • Only require the package --dev so it is absent from production images.
  • In AppServiceProvider::boot(), abort if app()->environment('production') and the rebuild command is somehow registered — a cheap, defensive check.
  • Document in the README that engineers must run php artisan db:show (or check .env) before invoking the command.

Gotchas and Tips

This drops tables — there is no undo. Unlike migrate:refresh, which rolls back in reverse order, the rebuild drops the schema outright. That means no down() methods run, so any seeder or fixture that relies on migration down() side effects is silently bypassed. Treat the command as a one-way door and always confirm DB_DATABASE before running it locally.

2020-era package vs. Laravel 11/12. The last release was September 2020, which predates Laravel 9, illuminate/* split constraints, and PHP 8.x attribute registration. Expect the package to still function (it is a thin wrapper over Artisan + DB + migration commands) but verify on a spike branch:

composer require webparking/laravel-db-rebuild:^1.2 --dev -W

If Composer forces an unrelated upgrade, stop — the maintenance tax is not worth the convenience over a two-line migrate:fresh && db:seed alias. If it resolves cleanly, pin the exact version in composer.json and commit the lockfile; do not let ^1.2 float in CI.

Foreign key constraint failures during drop. Some drivers (notably older MySQL and SQLite with foreign_key_constraints on) will refuse to DROP TABLE when FK dependencies exist, or will refuse to re-create them without explicit ordering. If the command fails mid-drop with a constraint error, check:

  • config/database.php → connections.mysql.foreign_key_constraints and driver version.
  • Whether any table has FK references added through a package migration you do not control.
  • Whether SET FOREIGN_KEY_CHECKS=0 is being issued by the command — if the implementation doesn't, you may need to run it yourself before invoking the command:
mysql -e 'SET FOREIGN_KEY_CHECKS=0' "$DB_DATABASE"
php artisan db:rebuild

This is the most common failure mode in practice and is worth documenting in your team's runbook.

Seeder class resolution is fiddly. If --class errors with "Target class [...] does not exist", it is almost always a namespace-escaping problem on the CLI. On bash: --class=Database\\Seeders\\CiSeeder. On PowerShell (Windows developers): --class="Database\Seeders\CiSeeder". Prefer a short class name if the package's resolver supports it, or wrap the invocation in a Composer script where the shell is not involved.

DDL inside transactions varies by driver. On MySQL, DROP TABLE and CREATE TABLE implicitly commit, so if the command tries to wrap the whole rebuild in DB::transaction() (or you add that yourself in a wrapper), you can get a half-migrated state on failure. On Postgres and SQLite, DDL is transactional — a failed rebuild leaves you with the pre-rebuild schema. Test the failure mode you actually get in your environment before relying on atomicity.

CI connection hygiene. In CI, DB_CONNECTION frequently defaults to sqlite (:memory:) when no DB_* env vars are set. That means db:rebuild may succeed against a throwaway in-memory database while your integration suite runs against MySQL, giving you a false green. Always export explicit DB_CONNECTION/DB_HOST/DB_DATABASE before the rebuild step, and log the connection name (php artisan db:show output) in the CI log so it is auditable.

Testing your own rebuild command. If you wrap db:rebuild (see extension points below), test it against a real database, not a mock. Mocking DB::statement and asserting DROP TABLE was called gives you false confidence — the failure modes are driver-level. Use a dedicated testing connection and assert schema state after the rebuild, not the queries it issued.

Extension points. Two patterns are cheap and effective when the stock command does not fit:

  1. Subclass the command. Register your own App\Console\Commands\RebuildDatabase extends Webparking\DbRebuild\Commands\... and override handle() to add pre-flight checks (environment guard, confirmation prompt, db:show log line) before calling parent::handle(). This is the cleanest way to add a production guard without forking.
  2. Wrap in a Composer script. For anything shell-level (env checks, SET FOREIGN_KEY_CHECKS, running a second command), a Composer script or Makefile target is more maintainable than modifying the package. The package remains upgradeable; your orchestration stays in your repo.

Debugging a partial rebuild. If the command exits mid-run, inspect the state before rerunning:

php artisan migrate:status

Tables that exist but whose migrations are not marked "Ran" indicate the drop phase succeeded and the migrate phase failed. This is usually a broken migration or a missing FK on a dropped-and-recreated table — the error text will point at the failing migration. Do not rerun blindly; fix the migration first, or the second run will fail the same way.

Abandonment risk is the real long-term gotcha. With a single release in 2020 and low star count, assume you will eventually fork or replace this. Keep your invocation isolated to one Composer script or one subclass so that a future migration to a two-line migrate:fresh && db:seed alias, or to a maintained alternative, is a one-file change rather than a sweep through every developer's shell history and every CI config.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console