У меня две фабрики: одна по категориям, а другая по продуктам. Когда я запускаю фабрику, я хочу создать 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();






$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 также будет лениво создавать эту модель и автоматически связывать ее
В Laravel 8 вы можете использовать Category :: factory () вместо вспомогательных методов factory (). И в модели категорий добавьте черту, используйте HasFactory;
Я использую другой синтаксис, но думаю, он сработает / вы можете его изменить
В вашей модели 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 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 категория.
Вам просто нужно передать CategoryFactory в category_id.
return [
'category_id' => Category::factory(),
// ...
];
Вы можете узнать больше о фабриках здесь: https://laravel.com/docs/8.x/database-testing#defining-relationships-within-factories
правда это то, что я только что видел в документации.
Если вы хотите создать несколько продуктов для каждой созданной категории, вы можете сделать что-то вроде этого:
// CategoryProductSeeder
$categories = Category::factory(50)->create();
$categories->each(function ($category) {
$categories->products()->saveMany(
Product::factory(10)->make()
);
});
я получаю undefined $ factory, мне нужно импортировать класс? не уверен, какой именно. то же самое с функцией factory () он говорит undefined. Я использую Laravel 8