Skip to content

Commit

Permalink
Ask the user if they want the inverse side of a relation
Browse files Browse the repository at this point in the history
  • Loading branch information
weaverryan committed Feb 27, 2018
1 parent 2fd2e0c commit c3ccf5f
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 19 deletions.
51 changes: 34 additions & 17 deletions src/Maker/MakeEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,6 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
// save the inverse side if it's being mapped
if ($newField->getMapInverseRelation()) {
$fileManagerOperations[$otherManipulatorFilename] = $otherManipulator;
} else {
// print message about it not being saved
$fileManagerOperations[] = sprintf(
'The inverse side of the relation was not mapped in "%s" because it lives in the vendor/ directory.',
$newField->getInverseClass()
);
}
$currentFields[] = $newFieldName;
} else {
Expand Down Expand Up @@ -554,8 +548,30 @@ function ($name) use ($targetClass) {
return $io->confirm(sprintf('Do you want to automatically delete orphaned <comment>%s</comment> objects (orphanRemoval)?', $owningClass), false);
};

$setMapInverseSide = function (EntityRelation $relation) {
$relation->setMapInverseRelation(!$this->isClassInVendor($relation->getInverseClass()));
$askInverseSide = function (EntityRelation $relation) use ($io) {
if ($this->isClassInVendor($relation->getInverseClass())) {
$relation->setMapInverseRelation(false);
}

// recommend an inverse side, except for OneToOne, where it's inefficient
$recommendMappingInverse = EntityRelation::ONE_TO_ONE === $relation->getType() ? false : true;

$getterMethodName = 'get'.Str::asCamelCase(Str::getShortClassName($relation->getOwningClass()));
if (EntityRelation::ONE_TO_ONE !== $relation->getType()) {
// pluralize!
$getterMethodName = Str::singularCamelCaseToPluralCamelCase($getterMethodName);
}
$mapInverse = $io->confirm(
sprintf(
'Do you want to add a new property to <comment>%s</comment> so that you can access/update <comment>%s</comment> objects from it - e.g. <comment>$%s->%s()</comment>?',
Str::getShortClassName($relation->getInverseClass()),
Str::getShortClassName($relation->getOwningClass()),
Str::asLowerCamelCase(Str::getShortClassName($relation->getInverseClass())),
$getterMethodName
),
$recommendMappingInverse
);
$relation->setMapInverseRelation($mapInverse);
};

switch ($type) {
Expand All @@ -572,7 +588,7 @@ function ($name) use ($targetClass) {
$relation->getOwningClass()
));

$setMapInverseSide($relation);
$askInverseSide($relation);
if ($relation->getMapInverseRelation()) {
$io->comment(sprintf(
'A new property will also be added to the <comment>%s</comment> class so that you can access the related <comment>%s</comment> objects from it.',
Expand All @@ -583,13 +599,14 @@ function ($name) use ($targetClass) {
$relation->getInverseClass(),
Str::singularCamelCaseToPluralCamelCase(Str::getShortClassName($relation->getOwningClass()))
));
}

if (!$relation->isNullable()) {
$relation->setOrphanRemoval($askOrphanRemoval(
$relation->getOwningClass(),
$relation->getInverseClass()
));
// orphan removal only applies of the inverse relation is set
if (!$relation->isNullable()) {
$relation->setOrphanRemoval($askOrphanRemoval(
$relation->getOwningClass(),
$relation->getInverseClass()
));
}
}

break;
Expand Down Expand Up @@ -633,7 +650,7 @@ function ($name) use ($targetClass) {
);
$relation->setOwningProperty($newFieldName);

$setMapInverseSide($relation);
$askInverseSide($relation);
if ($relation->getMapInverseRelation()) {
$io->comment(sprintf(
'A new property will also be added to the <comment>%s</comment> class so that you can access the related <comment>%s</comment> objects from it.',
Expand All @@ -660,7 +677,7 @@ function ($name) use ($targetClass) {
$relation->getOwningClass()
));

$setMapInverseSide($relation);
$askInverseSide($relation);
if ($relation->getMapInverseRelation()) {
$io->comment(sprintf(
'A new property will also be added to the <comment>%s</comment> class so that you can access the related <comment>%s</comment> object from it.',
Expand Down
35 changes: 33 additions & 2 deletions tests/Maker/FunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ public function getCommandTests()
'ManyToOne',
// nullable
'n',
// do you want to generate an inverse relation? (default to yes)
'',
// field name on opposite side - use default 'userAvatarPhotos'
'',
// orphanRemoval (default to no)
Expand All @@ -218,6 +220,31 @@ public function getCommandTests()
->updateSchemaAfterCommand()
];

yield 'entity_many_to_one_simple_no_inverse' => [MakerTestDetails::createTest(
$this->getMakerInstance(MakeEntity::class),
[
// entity class name
'UserAvatarPhoto',
// field name
'user',
// add a relationship field
'relation',
// the target entity
'User',
// relation type
'ManyToOne',
// nullable
'n',
// do you want to generate an inverse relation? (default to yes)
'n',
// finish adding fields
''
])
->setFixtureFilesPath(__DIR__.'/../fixtures/MakeEntityManyToOneNoInverse')
->configureDatabase()
->updateSchemaAfterCommand()
];

yield 'entity_one_to_many_simple' => [MakerTestDetails::createTest(
$this->getMakerInstance(MakeEntity::class),
[
Expand All @@ -231,6 +258,8 @@ public function getCommandTests()
'UserAvatarPhoto',
// relation type
'OneToMany',
// inverse side?
'y',
// field name on opposite side - use default 'user'
'',
// nullable
Expand Down Expand Up @@ -258,6 +287,8 @@ public function getCommandTests()
'User',
// relation type
'ManyToMany',
// inverse side?
'y',
// field name on opposite side - use default 'courses'
'',
// finish adding fields
Expand All @@ -283,6 +314,8 @@ public function getCommandTests()
'OneToOne',
// nullable
'n',
// inverse side?
'y',
// field name on opposite side - use default 'userProfile'
'',
// finish adding fields
Expand Down Expand Up @@ -310,8 +343,6 @@ public function getCommandTests()
* normally, we ask for the field on the *other* side, but we
* do not here, since the other side won't be mapped.
*/
// orphanRemoval (default to no)
'',
// finish adding fields
''
])
Expand Down
23 changes: 23 additions & 0 deletions tests/fixtures/MakeEntityManyToOneNoInverse/src/Entity/User.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity()
*/
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;

public function getId()
{
return $this->id;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace App\Tests;

use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Doctrine\ORM\EntityManager;
use App\Entity\User;
use App\Entity\UserAvatarPhoto;

class GeneratedEntityTest extends KernelTestCase
{
public function testGeneratedEntity()
{
self::bootKernel();
/** @var EntityManager $em */
$em = self::$kernel->getContainer()
->get('doctrine')
->getManager();

$em->createQuery('DELETE FROM App\\Entity\\User u')->execute();
$em->createQuery('DELETE FROM App\\Entity\\UserAvatarPhoto u')->execute();

$user = new User();
$em->persist($user);

$photo = new UserAvatarPhoto();
$photo->setUser($user);
$em->persist($photo);

$em->flush();
$em->refresh($photo);

$this->assertSame($photo->getUser(), $user);
}
}

0 comments on commit c3ccf5f

Please sign in to comment.