@HenLeiko

Сидер не видит фабрику, хотя она есть. В чём может быть проблема?

Делаю api на laravel и появилась проблема откуда не ожидалось, сидер перестал видеть фабрику, хотя все пространства имён на месте, сама фабрика тоже есть и я ей уже пользовался. Прошерстил разные топики на этот счёт, но проблема так и осталась.
Из моих предположений:
  • Что-то поломалось после дабовления пакета scribe
  • Что-то поломалось после дабовления пакета Pest


Ниже приведу модель, сидер, фабрику и json композера, а так же выхлоп после вызова db:seed

Модель

<?php

namespace App\Providers\Models;

use Database\Factories\GameFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Game extends Model
{
    /** @use HasFactory<GameFactory> */
    use HasFactory;

    protected $fillable = [
        'name',
        'description'
    ];

    public function tags()
    {
        return $this->belongsToMany(Tag::class);
    }
}


сидер

<?php

namespace Database\Seeders;

use App\Providers\Models\Game;
use App\Providers\Models\Tag;
use Illuminate\Database\Seeder;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
         User::factory(10)->create();
         Game::factory(150)->create();
         Tag::factory(30)->create();

    }
}


фабрика

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Providers\Models\Game>
 */
class GameFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        return [
            'name' => $this->faker->word(),
            'description' => $this->faker->paragraph(),
        ];
    }
}


composer.json

{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The skeleton application for the Laravel framework.",
    "keywords": ["laravel", "framework"],
    "license": "MIT",
    "require": {
        "php": "^8.2",
        "laravel/framework": "^11.9",
        "laravel/sanctum": "^4.0",
        "laravel/tinker": "^2.9"
    },
    "require-dev": {
        "fakerphp/faker": "^1.23",
        "knuckleswtf/scribe": "^4.38",
        "laravel/breeze": "^2.2",
        "laravel/pail": "^1.1",
        "laravel/pint": "^1.13",
        "laravel/sail": "^1.26",
        "mockery/mockery": "^1.6",
        "nunomaduro/collision": "^8.1",
        "pestphp/pest": "^3.5",
        "pestphp/pest-plugin-laravel": "^3.0",
        "phpunit/phpunit": "^11.0.1"
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-update-cmd": [
            "@php artisan vendor:publish --tag=laravel-assets --ansi --force"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi",
            "@php -r \"file_exists('database/database.sqlite') || touch('database/database.sqlite');\"",
            "@php artisan migrate --graceful --ansi"
        ],
        "dev": [
            "Composer\\Config::disableProcessTimeout",
            "npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite"
        ]
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true,
        "allow-plugins": {
            "pestphp/pest-plugin": true,
            "php-http/discovery": true
        }
    },
    "minimum-stability": "stable",
    "prefer-stable": true
}


spoiler

Error 

  Class "Database\Factories\Providers\Models\GameFactory" not found

  at vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php:843
    839▕     public static function factoryForModel(string $modelName)
    840▕     {
    841▕         $factory = static::resolveFactoryName($modelName);
    842▕ 
  ➜ 843▕         return $factory::new();
    844▕     }
    845▕ 
    846▕     /**
    847▕      * Specify the callback that should be invoked to guess factory names based on dynamic relationship names.

      +1 vendor frames 

  2   database/seeders/DatabaseSeeder.php:19
      App\Providers\Models\Game::factory()
      +23 vendor frames 

  26  artisan:13
      Illuminate\Foundation\Application::handleCommand()


Я просто не понимаю откуда берётся Providers в пути автозагрузки.
  • Вопрос задан
  • 176 просмотров
Решения вопроса 1
pickHabr
@pickHabr
Костыльных дел мастер
Я просто не понимаю откуда берётся Providers в пути автозагрузки
модель расположена в нестандартном месте
App\Providers\Models
от этой модели вызывается метод factory который относится к трейту HasFactory, там вызывается куда передается неймспейс твоей модели и подставляется к шаблону для неймспейса фабрики

Соответственно есть 2 пути решения:
1) перенести модель по пути App\Models (переносишь файл, обновляешь неймспейс)
2) объяснить laravel где искать класс:

В GameFactory
class GameFactory extends Factory
{
    protected $model = \App\Providers\Models\Game::class;
...


В app/Providers/AppServiceProvider.php
public function boot(): void {
     // ...  
    Factory::guessFactoryNamesUsing(function(string $modelName) {
         return 'Database\\Factories\\' . class_basename($modelName) . 'Factory';
    });
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы