phplaravelvoyager

Why can't Laravel find the Voyager Seeder?


I was working on a migration in my project and instead of running php artisan migrate I ran php artisan migrate:fresh and this then cleared all my tables and the data in them. Now my DB has all blank tables but now I am running into an issue when I am trying to seed it again. I am able to seed it with the seeders I have made but I am also using voyager and I am unable to run the voyager seeder.

The voyager docs says that I should run this command to run seed the voyager tables:

php artisan db:seed --class=VoyagerDatabaseSeeder

But when I run this, it gives me the following error:

 Illuminate\Contracts\Container\BindingResolutionException 

  Target class [Database\Seeders\VoyagerDatabaseSeeder] does not exist.

  at vendor/laravel/framework/src/Illuminate/Container/Container.php:835
    831▕ 
    832▕         try {
    833▕             $reflector = new ReflectionClass($concrete);
    834▕         } catch (ReflectionException $e) {
  ➜ 835▕             throw new BindingResolutionException("Target class [$concrete] does not exist.", 0, $e);
    836▕         }
    837▕ 
    838▕         // If the type is not instantiable, the developer is attempting to resolve
    839▕         // an abstract type such as an Interface or Abstract Class and there is

      +23 vendor frames 
  24  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

And this is how my directory is laid out:

enter image description here

And you can see that the VoyagerDatabaseSeeder.php does exist but for some reason, laravel can't seed it? Any ideas?

----------- Comments [ composer dump-autoload ] -------------

This was the result from composer dump-autoload:

mobile-mastery-latest git:(enhancement/auth-user) ✗ composer dump-autoload
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: arrilot/laravel-widgets
Discovered Package: bumbummen99/shoppingcart
Discovered Package: cartalyst/stripe-laravel
Discovered Package: facade/ignition
Discovered Package: fideloper/proxy
Discovered Package: fruitcake/laravel-cors
Discovered Package: intervention/image
Discovered Package: larapack/doctrine-support
Discovered Package: larapack/voyager-hooks
Discovered Package: laravel/tinker
Discovered Package: laravel/ui
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Discovered Package: tcg/voyager
Package manifest generated successfully.
Generated optimized autoload files containing 5855 classes
➜  mobile-mastery-latest git:(enhancement/auth-user) ✗ php artisan db:seed --class=VoyagerDatabaseSeeder

   Illuminate\Contracts\Container\BindingResolutionException 

  Target class [Database\Seeders\VoyagerDatabaseSeeder] does not exist.

  at vendor/laravel/framework/src/Illuminate/Container/Container.php:835
    831▕ 
    832▕         try {
    833▕             $reflector = new ReflectionClass($concrete);
    834▕         } catch (ReflectionException $e) {
  ➜ 835▕             throw new BindingResolutionException("Target class [$concrete] does not exist.", 0, $e);
    836▕         }
    837▕ 
    838▕         // If the type is not instantiable, the developer is attempting to resolve
    839▕         // an abstract type such as an Interface or Abstract Class and there is

      +23 vendor frames 
  24  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

----------- Comments [ adding use statement ] -------------

This is the voyager seeder:

<?php

use Illuminate\Database\Seeder;
use TCG\Voyager\Traits\Seedable;

class VoyagerDatabaseSeeder extends Seeder
{
    use Seedable;

    protected $seedersPath = __DIR__.'/';

    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $this->seed('DataTypesTableSeeder');
        $this->seed('DataRowsTableSeeder');
        $this->seed('MenusTableSeeder');
        $this->seed('MenuItemsTableSeeder');
        $this->seed('RolesTableSeeder');
        $this->seed('PermissionsTableSeeder');
        $this->seed('PermissionRoleTableSeeder');
        $this->seed('SettingsTableSeeder');
    }
}

Solution

  • So we stumbled upon this issue, and we were only able to find a workaround for this.

    Cause

    It looks like in Laravel 7 seeders were created without a namespace, like Voyager's seeders. But that is not the case for Laravel 8. Now, Laravel is looking for Seeders in namespace Database\Seeders; - so when you try to run the php artisan db:seed --class=VoyagerDatabaseSeeder, it will be unable to find it as it is not in the namespace it is looking for.

    Solution

    Moving Voyager seeders into "seeders" folder - the same folder as Laravel 8 seeders are - and adding a proper namespace (Database\Seeders) seems to have solved our problem (I think moving them is not necessary, but we did it to keep the project clean).


    We are now able to use the command, and use the Voyager seeders the same way we would use any other seeder.

    Please note that I'm not a very experienced engineer nor experienced with Voyager, so please take this solution with a grain of salt and forgive me possible inaccuracies in the answer :)