foundry icon indicating copy to clipboard operation
foundry copied to clipboard

Possibility to "merge" properties in user land

Open nikophil opened this issue 1 year ago • 1 comments

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:

  • make Factory::$attributeSet protected, and let the user deal with it "at his own risk"
  • create a new method Factory::mergeAttributes(array), but this may come at the cost of some complexity (should we "deeply" merge array, objects, factories, etc... ?
  • create a new method Factory::resolveAttribute(string) which could be used in some cases to access the state of a given attribute.

not sure what would be the best solution :thinking:

nikophil avatar Feb 02 '24 10:02 nikophil

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?

kbond avatar Feb 02 '24 14:02 kbond