【问题标题】:Laravel Faker Factory RelationshipLaravel Faker 工厂关系
【发布时间】:2021-06-29 19:42:29
【问题描述】:

我有两个工厂,一个用于类别,另一个用于产品。当我运行工厂时,我想为生成的每个类别创建 x 个产品。我将如何编写代码来生产这个?

类别的定义是这样写的:

return [
            'name' => $this->faker->word,
            'slug' => Str::slug($this->faker->unique()->word, '-'),
        ];

产品的定义是这样写的:

return [
                'category_id' => 1, //instead of 1 the category id used i want to be random
                'name' => $this->faker->word,
                'slug' => Str::slug($this->faker->unique()->word, '-'),
                'description' => $this->faker->paragraph,
                'price' => $this->faker->randomFloat(2, 0, 10000),
                'is_visible' => 1,
                'is_featured' => 1
            ];

如您所见,我对category_id 进行了硬编码,我不太确定如何让它自动生成并为每个存在的类别创建一个产品。我有这样写的类别的工厂,以创建 10 个项目

Category::factory()
                ->count(10)
                ->create();

我尝试了这个尝试和错误,认为它会起作用,但我收到一个错误 category_id cannot be null

Product::factory()
                ->has(Category::factory()->count(2))
                ->count(20)
                ->create();

【问题讨论】:

    标签: php laravel eloquent factory


    【解决方案1】:
        $factory->define(Product::class, function (Faker $faker) {
        return [
            'category_id' => factory(Category::class), //instead of 1 the category id used i want to be random
            'name' => $this->faker->word,
            'slug' => Str::slug($this->faker->unique()->word, '-'),
            'description' => $this->faker->paragraph,
            'price' => $this->faker->randomFloat(2, 0, 10000),
            'is_visible' => 1,
            'is_featured' => 1
        ];
    });
    

    通过将属性设置为 factory() 的实例,Laravel 也会懒惰地创建该模型并自动关联它

    【讨论】:

    • 我得到未定义的 $factory 我需要导入一个类吗?不确定是哪一个。与它说未定义的 factory() 函数相同。我正在使用 laravel 8
    • 在 Laravel 8 中,您可以使用 Category::factory() 代替 factory() 辅助方法。并在类别模型中添加一个特征,使用 HasFactory;
    【解决方案2】:

    我使用了不同的语法,但我认为它会起作用/你可以改变它

    在您的 Category.php 模型中

    public function products() {
        return $this->hasMany(Product::class);
    }
    

    seeder

    factory(App\Category::class, 10)->create()->each(function($c) {
        $c->products()->save(factory(App\Product::class)->make());
    }); // each Category will have 1 product
    

    Laravel Database Testing Relationships

    【讨论】:

      【解决方案3】:

      这对我有用,因为我使用的是 laravel 8。

      产品定义:

      return [
                  'category_id' => Category::factory(),
                  'name' => $this->faker->word,
                  'slug' => Str::slug($this->faker->unique()->word, '-'),
                  'description' => $this->faker->paragraph,
                  'price' => $this->faker->randomFloat(2, 0, 1000),
                  'is_visible' => 1,
                  'is_featured' => 1
              ];
      

      播种机:

      Product::factory()
                      ->has(Category::factory())->count(50)
                      ->create();
      

      创建了 50 个类别和 50 种产品。为每个产品分配 1 个类别。

      【讨论】:

        【解决方案4】:

        您只需将CategoryFactory 传递给category_id

        return [
            'category_id' => Category::factory(),
            // ...
        ];
        

        您可以在此处阅读有关工厂的更多信息:https://laravel.com/docs/8.x/database-testing#defining-relationships-within-factories

        【讨论】:

          【解决方案5】:

          如果您想为每个创建的类别创建多个产品,您可以执行以下操作:

          // CategoryProductSeeder
          $categories = Category::factory(50)->create();
          
          
          $categories->each(function ($category) {
              $categories->products()->saveMany(
                  Product::factory(10)->make()
              );
          });
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-05-01
            • 2016-08-18
            • 2020-12-28
            • 2018-06-13
            • 2017-10-22
            • 2015-12-09
            • 2021-07-08
            • 1970-01-01
            相关资源
            最近更新 更多