admin管理员组

文章数量:1123063

Just diving deeper into writing Tests for PHP applications and now I'm familiarizing with zenstruck/foundry.

Foundry offers diverse ways of creating entity instances. What causes me problems is the fact, that with foundry instantiation of objects means it will persist these objects early (when these methods are called: new / createMany, createSequence / etc.).

I know that foundry offers diverse ways to hook into instantiation process. But the question is not about solving the problems with foundry trickery.

First I want to know, is the association described below an indicator of bad ORM design? If so, I will change it and foundry will run fine without errors - no trickery required.

I have two entities: Account and AccountSettings - they are associated via OneToOne (the question also applies to OneToMany associations).

Account.php Entity:

    #[ORM\OneToOne(mappedBy: 'account', targetEntity: AccountSettings::class, orphanRemoval: true)]
    private $accountSettings;

AccountSettings.php Entity:

    #[ORM\OneToOne(inversedBy: 'accountSettings')]
    #[ORM\JoinColumn(nullable: false)]
    private ?Account $account = null;

Because I wanted to make sure that there are no non-associated AccountSetting objects in the database, I have set $account to be non-nullable.

Therefore I also have to create AccountSettings for each Account object created by calling AccountFactory::createMany(...).

That obviously fails with foundrys way of doing these creations - which includes persisting the objects: Because the Account object isn't saved yet, there is no database ID, so I can not create the AccountSettings object on the fly by calling AccountSettingsFactory::new().

No Database ID for Account is available yet, so that call would result in DB Exception:

"Integrity constraint violation: 19 NOT NULL constraint failed: account_settings.account_id".

I could simply remove the non-nullable attribute, but first I wanted to know: is this attribute really unsuitable/inappropriate for this kind of ORM association?

Just diving deeper into writing Tests for PHP applications and now I'm familiarizing with zenstruck/foundry.

Foundry offers diverse ways of creating entity instances. What causes me problems is the fact, that with foundry instantiation of objects means it will persist these objects early (when these methods are called: new / createMany, createSequence / etc.).

I know that foundry offers diverse ways to hook into instantiation process. But the question is not about solving the problems with foundry trickery.

First I want to know, is the association described below an indicator of bad ORM design? If so, I will change it and foundry will run fine without errors - no trickery required.

I have two entities: Account and AccountSettings - they are associated via OneToOne (the question also applies to OneToMany associations).

Account.php Entity:

    #[ORM\OneToOne(mappedBy: 'account', targetEntity: AccountSettings::class, orphanRemoval: true)]
    private $accountSettings;

AccountSettings.php Entity:

    #[ORM\OneToOne(inversedBy: 'accountSettings')]
    #[ORM\JoinColumn(nullable: false)]
    private ?Account $account = null;

Because I wanted to make sure that there are no non-associated AccountSetting objects in the database, I have set $account to be non-nullable.

Therefore I also have to create AccountSettings for each Account object created by calling AccountFactory::createMany(...).

That obviously fails with foundrys way of doing these creations - which includes persisting the objects: Because the Account object isn't saved yet, there is no database ID, so I can not create the AccountSettings object on the fly by calling AccountSettingsFactory::new().

No Database ID for Account is available yet, so that call would result in DB Exception:

"Integrity constraint violation: 19 NOT NULL constraint failed: account_settings.account_id".

I could simply remove the non-nullable attribute, but first I wanted to know: is this attribute really unsuitable/inappropriate for this kind of ORM association?

Share Improve this question asked 3 hours ago rubberchickenrubberchicken 11 bronze badge
Add a comment  | 

1 Answer 1

Reset to default 0

In short: no, it isn't.

In detail: You can create the 1-1 relation object 'AccountSettings' in the factory process 'new()' appanding the creation of the related object e.g. with 'with()'. Please keep the not null relation - It's the better DB design in my opinion.

use App\Entity\Account;
use App\Entity\AccountSettings;
use App\Factory\AccountFactory;
use App\Factory\AccountSettingsFactory;

$account = AccountFactory::new(['login' => 'fuba'])
    ->with([
         'body' => 'Post Body...',
         // AccountSettings will be used to create a new Setting for each User
         'setting' => AccountSettings::new(['name' => 'somebody', /* other params */]),
    ]);

There are many ways to match your problem. If u need further informations, pls ask.

Take a look at the following link, may be it will help u.

https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html

本文标签: