Skip to content

Commit d644104

Browse files
committed
fix: add unpersisted object to relation
1 parent 3e9650a commit d644104

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
@@ -355,12 +355,29 @@ protected function normalizeObject(object $object): object
355355

356356
$configuration = Configuration::instance();
357357

358-
if (!$configuration->isPersistenceAvailable() || !$configuration->persistence()->hasPersistenceFor($object)) {
358+
if (!$configuration->isPersistenceAvailable()) {
359359
return $object;
360360
}
361361

362+
$persistenceManager = $configuration->persistence();
363+
364+
if ($object instanceof Proxy) {
365+
$proxy = $object;
366+
$proxy->_disableAutoRefresh();
367+
$object = $proxy->_real();
368+
$proxy->_enableAutoRefresh();
369+
}
370+
371+
if (!$persistenceManager->hasPersistenceFor($object)) {
372+
return $object;
373+
}
374+
375+
if (!$persistenceManager->isPersisted($object)) {
376+
$persistenceManager->scheduleForInsert($object);
377+
}
378+
362379
try {
363-
return $configuration->persistence()->refresh($object, true);
380+
return $persistenceManager->refresh($object, force: true);
364381
} catch (RefreshObjectFailed|VarExportLogicException) {
365382
return $object;
366383
}

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)