2

I'm creating a project using Laravel, and today I have a problem I can't find how to solve in a "correct" way.

I have this migration class:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddCityAndCountryColumnToClient extends Migration {
    public function up() {
        Schema::table('clients', function (Blueprint $table) {
            $table->string('city')->nullable()->default(null);
            $table->string('country', 2)->nullable()->default(null);
        });
    }

    public function down() {
        Schema::table('clients', function (Blueprint $table) {
            $table->dropColumn('country');
            $table->dropColumn('city');
        });
    }
}

I have a bunch of tests based on a model for that table "clients" and they run perfectly fine, but after I added this migration, my tests fail every time just from the very start.

Now, I discovered that if I modify that migration class to this:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddCityAndCountryColumnToClient extends Migration {
    public function up() {
        Schema::table('clients', function (Blueprint $table) {
            $table->string('city')->nullable()->default(null);
            $table->string('country', 2)->nullable()->default(null);
        });
    }

    public function down() {
        Schema::table('clients', function (Blueprint $table) {
            // $table->dropColumn('country');
            // $table->dropColumn('city');
        });
    }
}

Now all my tests run perfectly fine. But I'm concerned about the fact that the "down" method is now actually doing nothing, when it is supposed to do the opposite of the "up" method.

My test database is an in-memory sqlite instance for speed purposes:

'sqlite_testing' => [
    'driver'   => 'sqlite',
    'database' => ':memory:',
    'prefix'   => '',
],

I have another two migrations with the same behavior. The strange this is I already did something like this (adding a string column) to one of those tables, and I had no need to comment the content of my "down" method on that class:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddPhotoColumnToClientsTable extends Migration
{
    public function up()
    {
        Schema::table('clients', function (Blueprint $table) {
            $table->string('photo')->nullable();
        });
    }

    public function down()
    {
        Schema::table('clients', function (Blueprint $table) {
            $table->dropColumn('photo');
        });
    }
}

So I don't know what's wrong with the "city" and "country" columns added on the first mentioned migration.

I created all those migration classes from the php artisan command line so I have not modified their default structure (the examples here have no comments to make them short), and I have checked also that none of those migrations have the wrong code on the "down" method.

Am I missing anything there, or is there some kind of limit I'm forgetting about SQLite or migrations?

Here is the result with the "down" method commented:

PHPUnit 4.8.23 by Sebastian Bergmann and contributors.

.............S.............................................

Time: 42.4 seconds, Memory: 47.25Mb

OK, but incomplete, skipped, or risky tests!
Tests: 59, Assertions: 215, Skipped: 1.

And this is the result if I uncomment any or all of the "down" method content lines:

PHPUnit 4.8.23 by Sebastian Bergmann and contributors.

E

Time: 1.74 seconds, Memory: 20.75Mb

There was 1 error:

1) AuthTest::a_client_user_can_login_via_api
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 no such column: country (SQL: CREATE TEMPORARY TABLE __temp__clients AS SELECT id, user_id, cell_phone, photo, created_at, updated_at, deleted_at, country FROM clients)

C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Connection.php:669
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Connection.php:629
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Connection.php:409
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Schema\Blueprint.php:83
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Schema\Builder.php:203
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Schema\Builder.php:128
C:\My Project\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:221
C:\My Project\database\migrations\2016_03_12_002857_add_city_and_country_column_to_client.php:28
C:\My Project\database\migrations\2016_03_12_002857_add_city_and_country_column_to_client.php:28
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Migrations\Migrator.php:233
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Migrations\Migrator.php:181
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Console\Migrations\RollbackCommand.php:63
C:\My Project\vendor\laravel\framework\src\Illuminate\Container\Container.php:507
C:\My Project\vendor\laravel\framework\src\Illuminate\Console\Command.php:169
C:\My Project\vendor\symfony\console\Command\Command.php:256
C:\My Project\vendor\laravel\framework\src\Illuminate\Console\Command.php:155
C:\My Project\vendor\symfony\console\Application.php:791
C:\My Project\vendor\symfony\console\Application.php:186
C:\My Project\vendor\symfony\console\Application.php:117
C:\My Project\vendor\laravel\framework\src\Illuminate\Console\Application.php:64
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php:159
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\InteractsWithConsole.php:25
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\DatabaseMigrations.php:12
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\TestCase.php:127
C:\Users\TheWindowsUser\AppData\Roaming\Composer\vendor\phpunit\phpunit\src\TextUI\Command.php:149
C:\Users\TheWindowsUser\AppData\Roaming\Composer\vendor\phpunit\phpunit\src\TextUI\Command.php:100

Caused by
PDOException: SQLSTATE[HY000]: General error: 1 no such column: country

C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Connection.php:408
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Connection.php:662
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Connection.php:629
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Connection.php:409
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Schema\Blueprint.php:83
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Schema\Builder.php:203
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Schema\Builder.php:128
C:\My Project\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:221
C:\My Project\database\migrations\2016_03_12_002857_add_city_and_country_column_to_client.php:28
C:\My Project\database\migrations\2016_03_12_002857_add_city_and_country_column_to_client.php:28
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Migrations\Migrator.php:233
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Migrations\Migrator.php:181
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Console\Migrations\RollbackCommand.php:63
C:\My Project\vendor\laravel\framework\src\Illuminate\Container\Container.php:507
C:\My Project\vendor\laravel\framework\src\Illuminate\Console\Command.php:169
C:\My Project\vendor\symfony\console\Command\Command.php:256
C:\My Project\vendor\laravel\framework\src\Illuminate\Console\Command.php:155
C:\My Project\vendor\symfony\console\Application.php:791
C:\My Project\vendor\symfony\console\Application.php:186
C:\My Project\vendor\symfony\console\Application.php:117
C:\My Project\vendor\laravel\framework\src\Illuminate\Console\Application.php:64
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php:159
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\InteractsWithConsole.php:25
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\DatabaseMigrations.php:12
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\TestCase.php:127
C:\Users\TheWindowsUser\AppData\Roaming\Composer\vendor\phpunit\phpunit\src\TextUI\Command.php:149
C:\Users\TheWindowsUser\AppData\Roaming\Composer\vendor\phpunit\phpunit\src\TextUI\Command.php:100

FAILURES!
Tests: 1, Assertions: 4, Errors: 1.

Update

By the way, I'm running all my Tests with the use Illuminate\Foundation\Testing\DatabaseMigrations; trait. No special config applied nor particular changes on the default tests classes provided by Laravel.

1 Answer 1

6

Either split up the drop into two separate actions or alternately pass an array to dropColumn of the columns you want dropped.

Either

Schema::table('clients', function (Blueprint $table) {
    $table->dropColumn('country');
});

Schema::table('clients', function (Blueprint $table) {
    $table->dropColumn('city');
});

or

$table->dropColumn(['country', 'city']);

see https://github.com/laravel/framework/issues/2979

Sign up to request clarification or add additional context in comments.

1 Comment

For anyone else stumbling across this issue, this solution works and should be marked as the answer. I went with adding each column to be dropped as part of an array $table->dropColumn(['country', 'city']);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.