mongodb / laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel (Moloquent)
https://www.mongodb.com/docs/drivers/php/laravel-mongodb/
MIT License
7.01k stars 1.43k forks source link

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

Closed Vittalks closed 4 years ago

Vittalks commented 7 years ago

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

nahueJ commented 7 years ago

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

Vittalks commented 7 years ago

@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

nahueJ commented 7 years ago

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.

Ravaelles commented 7 years ago

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.

travisneids commented 7 years ago

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);
    }
}
DevRubenArevalo commented 7 years ago

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' => 'qwiuey@gmail.com',       'sticker_id'  =>  'love'],
            ['email' => 'test@test.com',                'sticker_id'  =>  'do_good'],
            ['email' => 'asd@asd.com',                  'sticker_id'  =>  'love'],
            ['email' => 'rise@test.com',                '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.

vignesh007vicky commented 6 years ago

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 { /**

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

I3NLi commented 6 years ago

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