Skip to content

Commit 09f30d2

Browse files
committed
fix: add unpersisted object to relation
1 parent 17388bc commit 09f30d2

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

src/Persistence/PersistenceManager.php

+1
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ public function refresh(object &$object, bool $force = false): object
190190

191191
public function isPersisted(object $object): bool
192192
{
193+
// prevents doctrine to use its cache and think the object is persisted
193194
if ($this->strategyFor($object::class)->isScheduledForInsert($object)) {
194195
return false;
195196
}

src/Persistence/PersistentObjectFactory.php

+19-2
Original file line numberDiff line numberDiff line change
@@ -367,12 +367,29 @@ protected function normalizeObject(object $object): object
367367

368368
$configuration = Configuration::instance();
369369

370-
if (!$configuration->isPersistenceAvailable() || !$configuration->persistence()->hasPersistenceFor($object)) {
370+
if (!$configuration->isPersistenceAvailable()) {
371371
return $object;
372372
}
373373

374+
$persistenceManager = $configuration->persistence();
375+
376+
if ($object instanceof Proxy) {
377+
$proxy = $object;
378+
$proxy->_disableAutoRefresh();
379+
$object = $proxy->_real();
380+
$proxy->_enableAutoRefresh();
381+
}
382+
383+
if (!$persistenceManager->hasPersistenceFor($object)) {
384+
return $object;
385+
}
386+
387+
if (!$persistenceManager->isPersisted($object)) {
388+
$persistenceManager->scheduleForInsert($object);
389+
}
390+
374391
try {
375-
return $configuration->persistence()->refresh($object, true);
392+
return $persistenceManager->refresh($object, force: true);
376393
} catch (RefreshObjectFailed|VarExportLogicException) {
377394
return $object;
378395
}

tests/Integration/ORM/EntityRelationship/EntityFactoryRelationshipTestCase.php

+38
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
use Zenstruck\Foundry\Tests\Fixture\Entity\Contact;
3232
use Zenstruck\Foundry\Tests\Fixture\Entity\Tag;
3333

34+
use function Zenstruck\Foundry\Persistence\refresh;
3435
use function Zenstruck\Foundry\Persistence\unproxy;
3536

3637
/**
@@ -361,6 +362,43 @@ public function ensure_one_to_many_relations_are_not_pre_persisted(): void
361362
}
362363
}
363364

365+
/** @test */
366+
#[Test]
367+
#[DataProvider('provideCascadeRelationshipsCombinations')]
368+
#[UsingRelationships(Category::class, ['contacts'])]
369+
public function it_can_add_managed_entity_to_many_to_one(): void
370+
{
371+
$this->it_can_add_entity_to_many_to_one(
372+
static::categoryFactory()->create()
373+
);
374+
}
375+
376+
/** @test */
377+
#[Test]
378+
#[DataProvider('provideCascadeRelationshipsCombinations')]
379+
#[UsingRelationships(Category::class, ['contacts'])]
380+
public function it_can_add_unmanaged_entity_to_many_to_one(): void
381+
{
382+
$this->it_can_add_entity_to_many_to_one(
383+
static::categoryFactory()->withoutPersisting()->create()
384+
);
385+
}
386+
387+
private function it_can_add_entity_to_many_to_one(Category $category): void
388+
{
389+
self::assertCount(0, $category->getContacts());
390+
391+
$contact1 = static::contactFactory()->create(['category' => $category]);
392+
$contact2 = static::contactFactory()->create(['category' => $category]);
393+
394+
static::categoryFactory()::assert()->count(1);
395+
396+
self::assertCount(2, $category->getContacts());
397+
398+
self::assertSame(unproxy($category), $contact1->getCategory());
399+
self::assertSame(unproxy($category), $contact2->getCategory());
400+
}
401+
364402
/** @return PersistentObjectFactory<Contact> */
365403
protected static function contactFactoryWithoutCategory(): PersistentObjectFactory
366404
{

0 commit comments

Comments
 (0)