Search code examples
phplaravelmodelrelationshipfactory

how to access relations of laravel factory from inside another factory


I have a model called Company, and Fields are added to it via an observer after it is created:

    protected static function booted(): void
    {
        static::created(function (Company $company) {
            $company->fields()->createMany([
                ['name' => 'First Name', 'type' => \App\Enums\FieldType::TEXT],
                ['name' => 'Last Name', 'type' => \App\Enums\FieldType::TEXT],
                ['name' => 'Email Address', 'type' => \App\Enums\FieldType::EMAIL],
                ['name' => 'Phone Number', 'type' => \App\Enums\FieldType::PHONE],
            ]);
        });
    }

All of my relations are defined correctly.

I am trying to grab this relationship inside of another factory, called Lead.

Here is my setup:

seeder:

        \App\Models\Company::factory(10)
            ->hasLeads(10)
            ->hasUsers(10)
            ->create();

Here is my Lead factory definition:

    public function definition(): array
    {
        $company = Company::factory();

        return [
            'company_id' => $company,
            'fields' => [
                $company->fields->firstWhere('name', 'First Name')->id => fake()->firstName(),
                $company->fields->firstWhere('name', 'Last Name')->id => fake()->lastName(),
                $company->fields->firstWhere('name', 'Email Address')->id => fake()->safeEmail(),
                $company->fields->firstWhere('name', 'Phone Number')->id => fake()->phoneNumber(),
            ],
        ];
    }

this produces the following error:

Undefined property: Database\Factories\CompanyFactory::$fields

how can i get the fields relationship from the Company factory inside of my Lead factory? I would like this to work with the observer.


Solution

  • i figured it out:

        public function definition(): array
        {
            return [
                'company_id' => Company::factory(),
                'fields' => function (array $attributes) {
                    $company = Company::find($attributes['company_id']);
    
                    return [
                        $company->fields->firstWhere('name', 'First Name')->id => fake()->firstName(),
                        $company->fields->firstWhere('name', 'Last Name')->id => fake()->lastName(),
                        $company->fields->firstWhere('name', 'Email Address')->id => fake()->safeEmail(),
                        $company->fields->firstWhere('name', 'Phone Number')->id => fake()->phoneNumber(),
                    ];
                },
            ];
        }