I recently hit several pitfalls when using migration:rollback. Here are the common mistakes and how to catch them early with tests.
Common Mistakes
Adding and dropping columns in the same closure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // Bad
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('old_column');
$table->string('new_column');
});
// Good — split into two closures
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('old_column');
});
Schema::table('users', function (Blueprint $table) {
$table->string('new_column');
});
|
Dropping an index and column at the same time
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // Bad
Schema::table('users', function (Blueprint $table) {
$table->dropIndex('users_old_column_index');
$table->dropColumn('old_column');
});
// Good — drop the index first, then the column
Schema::table('users', function (Blueprint $table) {
$table->dropIndex('users_old_column_index');
});
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('old_column');
});
|
Dropping multiple columns must be in a single call
1
2
3
4
5
6
7
8
9
10
| // Bad
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('old_column');
$table->dropColumn('old_column2');
});
// Good
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('old_column', 'old_column2');
});
|
How to Automatically Validate Migrations
Running migration:rollback on a production database to test is too risky. A safer approach is to use PHPUnit + SQLite in-memory.
Add these two lines in the <php> block:
1
2
| <env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
|
2. Write a test
It doesn’t need to be complex – just make sure the migration runs without errors:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| namespace Tests\Feature;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Tests\TestCase;
class MigrationTest extends TestCase
{
use DatabaseMigrations;
public function testMigrationRunsSuccessfully()
{
$this->assertTrue(true);
}
}
|
Run vendor/bin/phpunit. If any migration has a problem, it will fail immediately. This way you can catch broken migrations right away every time you make changes.