Laravel-mongodb: ErrorException: Argument 2 passed to Illuminate\Database\Schema\Blueprint::build() must be an instance of Illuminate\Database\Schema\Grammars\Grammar

Created on 26 May 2017  路  8Comments  路  Source: jenssegers/laravel-mongodb

I'm using the MongoDB v3.4.4 with the latest Laravel v5.4.* I'm getting the following exception while unit testing only.

note: api's working fine with mongodb

ErrorException: Argument 2 passed to Illuminate\Database\Schema\Blueprint::build() must be an instance of Illuminate\Database\Schema\Grammars\Grammar, null given, called in laravel5.4/vendor/laravel/framework/src/Illuminate/Database/Schema/Builder.php on line 239 and defined

Sample model code

//this is for mongodb
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class Profile extends Eloquent
{
    protected $collection = 'profile';
    protected $connection = 'mongodb';
}

Sample unit testcase class

use Illuminate\Support\Facades\Artisan;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class ProfileApiTest extends TestCase
{
    use DatabaseMigrations;

    public function setUp()
    {
        parent::setUp();
        Artisan::call('migrate:refresh');
        Artisan::call('db:seed');
    }
}

Artisan::call('migrate:refresh'); fails with above ErrorException

what I'm doing wrong here?

Thanks

question

Most helpful comment

Quoting:
"I think it is better to replace dropIfExists with drop in your migrations or implement the dropIfExists logic using drop and hasCollection method like @MightyPork in your migrations."

Basically the problem is in dropIfExists function.

All 8 comments

At the migration file, do you have "use Jenssegers\Mongodb\Schema\Blueprint;" ?

@nahueJ

Sorry for late replay

in migration file i am using this use Illuminate\Database\Schema\Blueprint;

when i run php artisan migrate command its executed successfully, only problem while executing test cases facing issue this

I had the same error, i've gave up. I deleted the project, dropped the DB, clone again the repository i was working with, i run a fresh composer install and a fresh php artisan migrate.
I'm sorry that i can't be more helpful.

Quoting:
"I think it is better to replace dropIfExists with drop in your migrations or implement the dropIfExists logic using drop and hasCollection method like @MightyPork in your migrations."

Basically the problem is in dropIfExists function.

I was receiving the same error at first but able to move past it with the following in my migration classes:

<?php

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

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $collection) {
            $collection->index('email');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $collection) {
            $collection->drop();
        });
    }
}

For whatever reason, it seems to completely ignore $collection->dropIfExists(); but I've done enough for one day so I'll stick with $collection->drop(); for now.

The above results in all greens on the following test (with DatabaseMigrations):

<?php

namespace Tests\Unit\User;

use App\Models\User;
use Illuminate\Database\Eloquent\Collection;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class UserTest extends TestCase
{
    use DatabaseMigrations;

    public function setUp()
    {
        parent::setUp();

        $this->user = create(User::class);
    }

    /** @test */
    public function a_user_has_players()
    {
        $this->assertInstanceOf(Collection::class, $this->user->players);
    }
}

Make sure to remove the other default 'user' and 'password_resets' migrations if you are not using them when testing this. It will conflict with the normal way the migration rollback works i think.

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
use Jenssegers\Mongodb\Schema\Blueprint;

class AddSomeVoters extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        // Create the collection voter and make emails unique.
        Schema::create('voter', function(Blueprint $collection)
        {
            $collection->unique('email');
        });

        $voters =[
            // Add the stickers in the same document since there are a limited amount and its less database calls.
            // Had to add the non_dups to keep the emails field unique but still accessible within the same document.
            ['_id' => 'love',      'path' => '/assets/images/love.png','email' => 'non_dup_1'],
            ['_id' => 'do_good',   'path' => '/assets/images/doGood.png','email' => 'non_dup_2'],
            ['_id' => 'unite',     'path' => '/assets/images/unite.png','email' => 'non_dup_3'],
            ['_id' => 'rise',      'path' => '/assets/images/rise.png','email' => 'non_dup_4'],

            // Creating a few test emails.
            ['email' => '[email protected]',       'sticker_id'  =>  'love'],
            ['email' => '[email protected]',                'sticker_id'  =>  'do_good'],
            ['email' => '[email protected]',                  'sticker_id'  =>  'love'],
            ['email' => '[email protected]',                'sticker_id'  =>  'rise']
        ];

        // Insert them into mongodb database.
        DB::connection('mongodb')->collection('voter')->insert($voters);

    }

     /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('voter');
    }
}

This worked perfectly for me.
FIRST TIME MIGRATION.

php artisan migrate 
Migration table created successfully.
Migrating: 2017_07_16_211153_add_some_voters
Migrated:  2017_07_16_211153_add_some_voters

php artisan migrate:rollback
Rolling back: 2017_07_16_211153_add_some_voters
Rolled back:  2017_07_16_211153_add_some_voters

DOING THE MIGRATION AGAIN AFTER DOCUMENT WAS CREATED:

php artisan migrate
Migrating: 2017_07_16_211153_add_some_voters
Migrated:  2017_07_16_211153_add_some_voters

Still working.

I have deleted the default migration provided by laravel

and created a new users migration file

use Illuminate\Support\Facades\Schema;
use Jenssegers\Mongodb\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;

class CreateUserCollection extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $collections) {
$collections->increments('id');
$collections->string('name');
$collections->string('email')->unique();
$collections->string('password');
});
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::dropIfExists('users');
}

}

but still

root@system3:/var/www/html/mongolaravel/jen/laravel# php artisan migrate:rollback

In Blueprint.php line 83:

Type error: Argument 2 passed to Illuminate\Database\Schema\Blueprint::build() must be an instance of Illuminate\Database\Schema\Grammars\Grammar
, null given, called in /var/www/html/mongolaravel/jen/laravel/vendor/laravel/framework/src/Illuminate/Database/Schema/Builder.php on line 252

and also password feild not created

try replace Schema::dropIfExists() with Schema::drop()

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sanjay1688 picture sanjay1688  路  3Comments

sebastiaanluca picture sebastiaanluca  路  3Comments

bastiendonjon picture bastiendonjon  路  3Comments

pirmax picture pirmax  路  3Comments

geofflancaster picture geofflancaster  路  3Comments