【问题标题】:Laravel 8, Model factory class not foundLaravel 8,找不到模型工厂类
【发布时间】:2021-01-04 16:26:14
【问题描述】:

所以当使用 laravel 8.x 中引入的新模型工厂类时,我遇到了这个奇怪的问题,说 laravel 找不到与模型对应的工厂。我得到这个错误

PHP Error:  Class 'Database/Factories/BusinessUserFactory' not found in .....

虽然我关注了 laravel 文档,但我不知道发生了什么

这是BusinessUser

<?php

namespace App;

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

class BusinessUser extends Model
{
    use HasFactory;
}

和工厂

<?php

namespace Database\Factories;

use App\BusinessUser;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

class BusinessUserFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = BusinessUser::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'name' => "dsfsf"
        ];
    }
}


非常感谢任何想法或线索。

【问题讨论】:

  • 那个工厂类的文件名是什么?您是否升级到 8 而不是全新安装,如果是这样,您可能缺少该目录的自动加载指令
  • 文件名是BusinessUserFactory.php,是的,我升级到了laravel 8
  • 我遇到了一个类似的错误,在一个为 Laravel 8 调用工厂更新的测试中,抛出一个错误,说找不到类“Database\Factories\Entity”。在工厂中使用 App\Models\Entity。自动加载已更新如下。

标签: php laravel


【解决方案1】:

这似乎是一个 laravel 核心问题!它是由位于Illuminate\Database\Eloquent\Factories\Factory.php 中的modelName() 方法引起的

问题已在 10 天前由 laravel 维护人员在此提交中修复 Fix commit 和此版本 8.82.0

您可以通过将 laravel 版本升级到 8.82.0

来解决此问题

希望这可以为您节省一些时间。干杯!

【讨论】:

    【解决方案2】:

    将此添加到AppServiceProvider::boot() 以防止模型猜测的命名空间。

    Factory::guessFactoryNamesUsing(function (string $modelName) {
            return 'Database\\Factories\\' . Arr::last(explode('\\', $modelName)) . 'Factory';
        });
    

    【讨论】:

      【解决方案3】:

      在我自己的例子中,它发生在一个 Laravel 8 项目中,即它不是我从 Laravel 7 升级的项目。我最近在composer update 之后注意到了这一点。

      1:创建模型时,旁边创建工厂

      php artisan make:model BusinessUser -f // -f creates the factory
      

      2:对于您的旧型号,请注释掉 use HasFactory; 或创建工厂

      php artisan make:factory BusinessUserFactory -m
      

      【讨论】:

        【解决方案4】:

        今天我将我的项目从Laravel 7升级到Laravel 8并在服务器上在线更新后遇到以下问题。

        Trait 'Illuminate\Database\Eloquent\Factories\HasFactory' not found
        

        即使我已经更新了composer.json @lagbox 在回答中给出的自动加载指令,但它并没有为我解决问题。

        最后我更新了完整的vendors 在线文件夹,解决了我的问题。

        【讨论】:

        • “更新的完整供应商”是什么意思?如果不这样做,您是如何升级项目的?
        • 每当我们在 Laravel 网站上离线更新任何包时,我们可能需要将供应商文件夹从离线替换为在线,因为供应商文件夹中有新的包文件。使用终端在服务器上在线更新供应商文件夹的其他方法,但某些服务器不支持它。
        • 请通过编辑将所有此类解释添加到您的答案中 - 您是如何确切做到这一点的? “替换供应商文件夹”听起来像是一些手动过程,最好通过适当的部署来解决
        【解决方案5】:

        运行composer dump-autoload 可能一切都很完美。它发生在我身上。

        【讨论】:

          【解决方案6】:

          我遇到了同样的问题,但原因不同。如果您在测试的setUp 函数中使用工厂,请确保:

          1. 您正在扩展 Tests\TestCase(而不是 PHPUnit\Framework\TestCase
          2. setUp 函数的第一行应该是 parent::setUp();(我错过了这个)

          【讨论】:

          • 这看起来对我来说会发生什么 - 我唯一一次得到这个错误是当我在测试类的 setup 方法中调用工厂时。但是,我的代码设置就像您在此处提到的那样,但我仍然收到错误消息。 (错误:找不到类“数据库\工厂\实体”)
          【解决方案7】:

          您需要确保命名空间是相同的:如下所示:否则这会让您大吃一惊。厂名是name of the model+Factory

          例如app\models\User- 将匹配到 database/factories/UserFactory

          最后确保你运行:composer dumpautoload

          【讨论】:

          • 这就是我的情况。我将我的类分组到子文件夹中,这导致了这里的问题。在工厂中添加相同的子文件夹结构后,一切都很好。
          • @SvetoslavStefanov - 我遇到了和你类似的问题,你能解释一下你是如何处理工厂中的子文件夹结构的吗?目前,我正在使用以域为中心的文件夹结构,因此我的模型包含在 src/Domain/Client/Models/Client 中,而 laravel 最终在 database/factories/Domain/Client/Models/ClientFactory 中搜索工厂,这阻止了我从能够播种我的数据库
          • @SoggyHedgehoggy - 我的问题是:我有这个文件夹结构: - 模型 - - 组织 - - - OrganizationMembers - - 文章 - - - 文章 - - - ArticleAttachments 应该复制到“工厂”文件夹。 “工厂”文件夹应等于“模型”文件夹。如果你看到 Laravel 正在搜索这条路径,是什么阻止你在那里创建模型并能够播种?
          • @SoggyHedgehoggy 也不要忘记在移动后更改工厂的命名空间。当您向工厂类添加新的子文件夹时,命名空间不会是 namespace Database\Factories ,而是会变成 namespace Database\Factories\Client
          【解决方案8】:

          我正在从 laravel 7 迁移到 8。

          在将我的头撞到墙上一段时间并查看源代码之后,我看到您可以选择使用模型上的newFactory 方法覆盖为模型调用的工厂类。

          然后我也注意到它IS 在文档中 (https://laravel.com/docs/8.x/database-testing#creating-models) - 我第一次阅读它时只是不明白它的含义。现在我知道了。

          我通过以下方式解决了这个问题:

          <?php
          
          namespace My\Fancy\Models;
          
          use Database\Factories\SomeFancyFactory;
          use Illuminate\Database\Eloquent\Factories\HasFactory;
          use Illuminate\Database\Eloquent\Model;
          
          class SomeClass extends Model
          {
              use HasFactory;
          
              /** @return SomeFancyFactory */
              protected static function newFactory()
              {
                  return SomeFancyFactory::new();
              }
          }
          

          在此更改之后,我的测试按预期通过了。

          【讨论】:

          • 我不得不这样做,但这不是我最喜欢的。
          • 我使用了成百上千个不同的 SDK。 Laravel 是因其漂亮的网站而赢得的最不必要的复杂网站。
          • 解决这个问题的最简单/最干净的方法是在您的工厂手动设置模型。受保护的 $model = Model::class;
          【解决方案9】:

          显然,您还必须尊重文件夹结构。例如,如果您在以下路径中有用户模型:app\Models\Users\User,则相应的工厂应位于database\factories\Users\UserFactory

          【讨论】:

          • 谢谢,它对我有用。在模型所在位置更改命名空间后。然后运行 ​​composer dump & php artisan optimize:clear database seeding completed.
          【解决方案10】:

          如果您从以前的版本升级到 8,您可能缺少 composer.jsonDatabase\Factories 命名空间的自动加载指令:

          "autoload": {
              "psr-4": {
                  "App\\": "app/",
                  "Database\\Factories\\": "database/factories/",
                  "Database\\Seeders\\": "database/seeders/"
              }
          },
          

          您也可以删除 classmap 部分,因为它不再需要。

          进行这些更改后运行composer dump

          Laravel 8.x Docs - Upgrade Guide - Database - Seeder and Factory Namespace

          【讨论】:

          • 如果您还没有升级到 8,但在版本 8 上开始了一个项目,那会是什么问题?
          • 另外,之前的database/seeds目录要重命名为database/seeders
          猜你喜欢
          • 2023-02-04
          • 2021-02-02
          • 2020-12-28
          • 2017-04-11
          • 2023-03-03
          • 2021-01-26
          • 2018-05-18
          • 2021-01-31
          • 2021-11-26
          相关资源
          最近更新 更多