私は2つのDoctrineエンティティ(Environment
およびEnvironmentConfig
)を持っています。彼らはbi-directional OneToOneの関係を持っています。Doctrine OneToOne ZF2フィールドセットを使用した双方向および単方向の保存/ハイドレーティング
各エンティティには独自のFieldsetがあり、再利用が容易です。
Environment
を作成するには、EnvironmentConfig
も使用できますが、必須ではありません。同時にそれらを作ることを可能にするために私はEnvironmentFieldset
とEnvironmentConfigFieldset
を使用するEnvironmentForm
を持っています。
フォームが正しくレンダリングされます。ただし、Environment
は保存されますが、EnvironmentConfig
は保存されません。
私はこれを設定する際に間違っていて、それを修正する方法はどこですか?
ゲッタ/セッタを省略した以下のコードは多すぎます。
エンティティ
// abstract class AbstractEntity has $id + getters/setters.
class Environment extends AbstractEntity
{
/**
* @var string
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
protected $name;
/**
* @var EnvironmentConfig
* @ORM\OneToOne(targetEntity="Environment\Entity\EnvironmentConfig", inversedBy="environment")
*/
protected $config;
/**
* @var EnvironmentScript
* @ORM\OneToOne(targetEntity="EnvironmentScript")
*/
protected $script;
//Getters/setters
}
class EnvironmentConfig extends AbstractEntity
{
/**
* @var string
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
protected $name;
/**
* @var Environment
* @ORM\OneToOne(targetEntity="Environment\Entity\Environment", mappedBy="config")
*/
protected $environment;
//Getters/setters
}
フィールドセット
class EnvironmentFieldset extends AbstractFieldset
{
/**
* {@inheritdoc}
*/
public function init()
{
//Loads id element validation
parent::init();
$this->add([
'name' => 'name',
'type' => Text::class,
'options' => [
'label' => _('Name'),
'label_attributes' => [
'class' => 'col-xs-2 col-form-label',
],
],
'attributes' => [
'id' => 'name',
'class' => 'form-control'
],
]);
$this->add([
'name' => 'environment_config',
'type' => EnvironmentConfigFieldset::class,
'options' => [
'use_as_base_fieldset' => false,
],
]);
$this->add([
'type' => ObjectSelect::class,
'name' => 'environment_script',
'options' => [
'object_manager' => $this->getEntityManager(),
'target_class' => EnvironmentScript::class,
'property' => 'id',
'display_empty_item' => true,
'empty_item_label' => '---',
'label_generator' => function ($targetEntity) {
return $targetEntity->getId() . ' - ' . $targetEntity->getName();
},
],
]);
}
}
class EnvironmentConfigFieldset extends AbstractFieldset
{
/**
* {@inheritdoc}
*/
public function init()
{
//Loads id element validation
parent::init();
$this->add([
'name' => 'name',
'type' => Text::class,
'options' => [
'label' => _('Name'),
'label_attributes' => [
'class' => 'col-xs-2 col-form-label',
],
],
'attributes' => [
'id' => 'name',
'class' => 'form-control'
],
]);
}
}
フォーム
class EnvironmentForm extends AbstractForm
{
/**
* EnvironmentForm constructor.
* @param null $name
* @param array $options
*/
public function __construct($name = null, array $options)
{
//Also adds CSRF
parent::__construct($name, $options);
}
/**
* {@inheritdoc}
*/
public function init()
{
//Call parent initializer. Adds submit button.
parent::init();
$this->add([
'name' => 'environment',
'type' => EnvironmentFieldset::class,
'options' => [
'use_as_base_fieldset' => true,
],
]);
}
}
編集:追加デバッグデータと以下の機能でpersist()
ライン上で行うデバッグの上AddAction()
。
public function addAction($formName, array $formOptions = null, $route, array $routeParams = [])
{
if (!$this->formElementManager instanceof FormElementManagerV2Polyfill) {
throw new InvalidArgumentException('Dependency FormElementManagerV2Polyfill not set. Please check Factory for this function.');
}
if (!class_exists($formName)) {
throw new ClassNotFoundException('Given class could not be found. Does it exist?');
}
/** @var AbstractForm $form */
$form = $this->getFormElementManager()->get($formName, (is_null($formOptions) ? [] : $formOptions));
/** @var Request $request */
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
$entity = $form->getObject();
$this->getEntityService()->getEntityManager()->persist($entity);
$this->getEntityService()->getEntityManager()->flush();
$this->flashMessenger()->addSuccessMessage(
_('Successfully created object.')
);
$this->redirectToRoute($route, $this->getRouteParams($entity, $routeParams));
}
}
return [
'form' => $form,
'validationMessages' => $form->getMessages() ?: '',
];
}
ああ超感謝!その答えについての最悪の事は:私はいつもそれをすることがあったので、それは問題ではなく、私が自動的にして忘れてしまったものでした。思い出してくれてありがとう、Doctrineの基本を忘れて自分自身を苦しめている:() – Nukeface