1

Doctrine2 には、私のプロジェクトに役立つ組み込み型「配列」があります。スカラー型の配列で完全に機能します。しかし、今はオブジェクトの配列を使いたいと思っています。このようなもの:

/**
 * @ORM\Entity
 */
class MyEntity {

    /**
     * @var MyEntityParameter[] array of MyEntityParameter instances
     *
     * @ORM\Column(name="parameters", type="array", nullable=true)
     *
     */
    private $parameters;

}

MyEntityParameter は、シリアル化できるクラスです。Symfony の Form Builder でも使用しています。

MyEntityParameter インスタンスのフィールドが変更された場合、Doctrine はそれを検出せず、したがってレコードを更新しないことを除いて、私の計画は完全に機能します。配列要素を削除または追加すると、Doctrine がそれを検出します。これは、フィールドを変更してもクラス インスタンス オブジェクト ID が変更されないために発生することを認識していますが、Doctrine がこの変更を検出できるようにするにはどうすればよいでしょうか?

4

2 に答える 2

1

私は私にとって有効な解決策を見つけました。それほどエレガントではないと思いますが、この問題を解決する良い方法がない場合は、私や他の人にとってうまくいく可能性があります.

まず、オブジェクトを配列に保持するのではなく、配列を保持することにしました。ただし、MyEntityParameterSymfony のフォーム ビルダーでクラスを使用したいと考えています。この場合、アイデアはフィールドのマッピングを無効にすることです:

フォーム ビルダーでは、次のことを行います。

// Acme/Bundle/DemoBundle/Form/Type/MyEntityType.php

// ...

class MyEntityType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('parameters', 'collection', array(
            'mapped' => false, // do not map this field
            'type' => new MyEntityParameterType(),
            // ... other options ...
        ));
    }

}

子型 ( MyEntityParameterType) では、「data_class」をMyEntityParameter(問題とは関係がないため、コードは表示しません) に設定します。

ここで必要なのは、このマップされていないフィールドのデータを手動で入力して処理することだけです。

コントローラーで:

public function editAction($id, Request $request)
{
    // ...

    // $object is an instance of MyEntity
    $form = $this->createForm(new MyEntityType(), $object);

    $parameters = $object->getParameters();
    if ($parameters) {
        foreach ($parameters as $key => $parameter)
        {
            $form->get('parameters')->add($key, new MyEntityParameterType(),
                array(
                   // here I assume that the constructor of MyEntityParameter
                   // accepts the field data in an array format
                  'data' => new MyEntityParameter($parameter),
                )
            );
        }
    }

    if ($request->isMethod('POST')) {
        $form->submit($request);
        $parameters = array();
        foreach ($form->get('parameters')->all() as $parameter) {
            // here first getData() gives MyEntityParameter instance
            // and the second getData() is just a method of MyEntityParameter
            // that returns all the fields in an array format
            $parameters[] = $parameter->getData()->getData();
        }
        $object->setParameters($parameters);
        // if the parameters were changed in the form,
        // this change will be detected by UnitOfWork
    }

    // ...
}
于 2013-11-03T20:16:14.150 に答える
0

以前にこの問題に遭遇したことを覚えています。私にとってうまくいった回避策は、エンティティ プロパティが変更されたことを Doctrine が認識できるように新しいオブジェクトを設定し、永続化したい変更を含むオブジェクトを設定することでした。

$parameters = $entity->getParameters();
$parameters->foo = "bar";

$entity->setParameters(new MyEntityParameter());
$entity->setParameters($parameters);

$em->persist($entity);

インスタンスの配列のMyEntityParameter場合、次のコードが機能する可能性があります。

$parameters = $entity->getParameters();
$parameters[3]->foo = "bar"; // Just an example

$entity->setParameters(array(new MyEntityParameter()));
$entity->setParameters($parameters);

$em->persist($entity);
于 2013-11-03T19:22:36.510 に答える