Group
推奨される方法は、インスタンス化中にエンティティを提供するために、必要に応じてエンティティ リポジトリなどのファクトリと組み合わせて、コンストラクタの引数内に関連付けられたエンティティ オブジェクトを要求することです。これにより、エンティティが常に有効な状態になります。
src/Entity/Person.php
namespace App\Entity;
/**
* @ORM\Entity(repositoryClass="App\Repository\PersonRepository")
*/
class Person
{
//...
public function __construct($name, Group $group)
{
$this->setName($name);
$this->setGroup($group);
}
//...
}
src/リポジトリ/PersonRepository.php
namespace App\Repsotory;
use App\Entity\Group;
use App\Entity\Person;
class PersonRepository
{
const DEFAULT_GROUP = 122;
public function create($name, Group $group = null)
{
if (null === $group) {
$group = $this->_em->getReference(Group::class, self::DEFAULT_GROUP);
}
$person = new Person($name, $group);
$this->_em->persist($person);
return $person;
}
}
これにより、Doctrine ORM Entity Manager のみに依存して、デフォルトのグループの関連付けを維持できます。
$person = $em->getRepository(Person::class)->create('Mike');
$group = $person->getGroup();
echo $group->getId(); //outputs: 122
$em->flush();
このアプローチを Symfony で拡張して、doctrine エンティティ リポジトリの代わりにクエリ サービスを使用し、エンティティのインスタンス化を処理する中央の場所を提供できます。
Symfony 3.4+ では、リポジトリ サービス
を使用して、EntityManagerInterface
.
src/Service/PersonCreateQuery.php
namespace App\Service;
use App\Entity\Group;
use App\Entity\Person;
use Doctrine\ORM\EntityManagerInterface;
class PersonCreateQuery
{
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
public function __invoke($name)
{
$group = $this->em->getReference(Group::class, 122);
$person = new Person($name, $group);
$this->em->persist($person);
return $person;
}
}
依存性注入を使用してクエリ サービスを取得し、Symfony フォームやコントローラーなどで必要に応じて使用できるようになりました。
namespace App\Controller;
use App\Service\PersonCreateQuery;
class PersonController
{
public function createAction(PersonCreateQuery $query)
{
$person = $query('Mike');
$this->getDoctrine()->getManager()->flush();
//...
}
}
注: の使用法は$em->getReference()
に置き換えることができます$em->find()
。using$em->getReference()
はデータベースへのクエリを防ぎますが、参照が無効な場合は例外をスローしますが、 using$em->find()
は代わりに戻りnull
ます。
もう 1 つの方法は、エンティティでライフサイクル コールバックを使用するか、イベント リスナーを使用してより複雑な機能を実行することです。ただし、これにより、エンティティが永続化されるまで無効な状態でインスタンス化されます。
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
*/
class Person
{
const DEFAULT_GROUP = 122;
/** @ORM\Column(type="string") */
private $name = 'Mike';
/**
* @ORM\ManyToOne(targetEntity="Group", inversedBy="persons")
* @ORM\JoinColumn(referencedColumnName="id")
*/
private $group;
//....
public function setGroup(Group $group)
{
$this->group = $group;
$group->addPerson($this);
}
/**
* @param LifecycleEventArgs $event
* @ORM\PrePersist
*/
public function onPrePersist(LifecycleEventArgs $event)
{
if (!$this->group instanceof Group) {
/** set default group if not specified */
$group = $event->getEntityManager()->getReference(Group::class, self::DEFAULT_GROUP);
$this->setGroup($group);
}
}
}
Person エンティティを永続化すると、他の場所で明示的に設定されていない場合、グループが追加されます。
$person = new Person();
$person->setName('Foo Bar');
$em->persist($person); //persist or do nothing if already persisted
$group = $person->getGroup();
echo $group->getId(); //outputs: 122
$groupPerson = $group->getPerson();
echo $groupPerson->getName(); //outputs: Foo Bar
$em->flush(); //save to database
正気を保つために、ドクトリン イベントのドキュメントへのリンクを次に示します。