zenstruck / foundry

A model factory library for creating expressive, auto-completable, on-demand dev/test fixtures with Symfony and Doctrine.
https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html
MIT License
643 stars 70 forks source link

Possibility to "merge" properties in user land #553

Open nikophil opened 8 months ago

nikophil commented 8 months ago

From time to time there is the need to "merge" properties.

Given the following code:

// BlogPostFactory

public function defaults(): array
{
    return [
        'tags' => []
    ];
}

public function taggedWithPhp(): static 
{
    return $this->withAttributes(['tags' => ['php']]);
}

public function taggedWithSymfony(): static 
{
    return $this->withAttributes(['tags' => ['symfony']]);
}

It is not possible have a nice fluent api to have both tags php and symfony. I could do something like BlogPostFactory::createOne(['tags' => ['php', 'symfony']]), but real world examples are much less naive :)

Another example would be with a bitmask:

$filePermissionsFactory->withRead()->withWrite()->withExecute();

I think there could be several solutions to mitigate this problem:

not sure what would be the best solution :thinking:

kbond commented 8 months ago

Does this work?

// BlogPostFactory

public function defaults(): array
{
    return [
        'tags' => []
    ];
}

public function taggedWithPhp(): static 
{
    return $this->beforeInstantiate(function(array $attributes) {
        $attribtues['tags'][] = 'php';

        return $attributes;
    });
}

public function taggedWithSymfony(): static 
{
    return $this->beforeInstantiate(function(array $attributes) {
        $attribtues['tags'][] = 'symfony';

        return $attributes;
    });
}

If so, this feels like the best method to give complete control. We could make a helper but, like you say, do we deep merge?