My data model looks like this:
An Order contains between 1 and N Products
, a Product
has a single Category
.
I have 3 Factories, one for each entity: OrderFactory
, ProductFactory
, CategoryFactory
. In them, I setup default data:
namespace DatabaseFactories;
use AppCategory;
use AppProduct;
use IlluminateDatabaseEloquentFactoriesFactory;
class ProductFactory extends Factory
{
protected $model = Product::class;
public function definition()
{
$name = $this->faker->realText(20);
return [
'category_id' => Category::factory(),
'reference' => str_replace(' ', '', $name),
'name' => $name,
'price' => $this->faker->randomFloat(2, 1.00, 200.00),
];
}
}
namespace DatabaseFactories;
use AppCategory;
use IlluminateDatabaseEloquentFactoriesFactory;
class CategoryFactory extends Factory
{
protected $model = Category::class;
public function definition()
{
return [
'label' => $this->faker->realText(20),
'description' => $this->faker->text,
];
}
}
I want for one particular test to create an Order containing 5 products of a Category
named my specific category label
. I tried to do it like so:
$order = Order::factory()
->state([
'number' => 014789012,
])
->has(
Product::factory()
->count(3)
->has(
Category::factory()->state([
'label' => 'my specific category label',
])
)
)
->create();
But the Category->label
is not edited and remains the default one defined in CategoryFactory
. Why?
2
Answers
I made a mistake by using
has()
instead offor()
on myProduct
<=>Category
relation: as it is a OneToMany relationship, we need to usefor()
, like so:You can do like this too I guess