1

ManyToOne リレーションで Doctrine の ObjectSelect を使用するのに少し問題があります。

ManyToMany を使用した以下の関係は、100% 追加および編集できます。私の編集フォームには、現在の選択内容が問題なく取り込まれています。

この問題は ManyToOne 関係で発生します。フォームに現在の選択が取り込まれていないようです。

Task エンティティをフォームにバインドする前にダンプしようとしましたが、100% 正しいように見えます。すべての関係がエンティティに取り込まれています。

ただし、バインドした後、現在の値が選択されていない状態でフォームが表示されます。

タスク エンティティ:

/**
 * @ORM\Entity
 * @ORM\Table(name="tasks")
 */
class Task
{

        /**
         * @ORM\Id
         * @ORM\Column(type="integer");
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
    ...
        /**
         * @ORM\ManyToOne(targetEntity="Category")
         * @ORM\JoinColumn(name="category_id", referencedColumnName="id")
         */
        protected $category;
    ...    
        /**
         * @ORM\ManyToMany(targetEntity="ZDUser\Entity\User")
         * @ORM\JoinTable(name="tasks_assigned_user_linker",
         *        joinColumns={@ORM\JoinColumn(name="task_id", referencedColumnName="id")},
         *        inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}
         * )
         */
        protected $assignedUsers;

        /**
         * Initialize
         */
        public function __construct()
        {
                $this->assignedUsers = new ArrayCollection();
        }

        /**
         * We need a few getters and setters
         */
        public function getId()
        {
                return $this->id;
        }
        public function setId($id)
        {
                $this->id = $id;
        }

        public function getCategory() {
                return $this->category;
        }
        public function setCategory(Category $category) {
                $this->category = $category;
        }

        public function getAssignedUsers() {
                return $this->assignedUsers;
        }
        public function addAssignedUsers(Collection $users) {
                foreach ($users as $user) {
                        $this->assignedUsers->add($user);
                }
        }
        public function removeAssignedUsers(Collection $users) {
                foreach ($users as $user) {
                        $this->assignedUsers->removeElement($user);
                }
        }
}

私は自分のエンティティのほとんどで ManyToOne を使用しています。この方法は少し簡単で拡張性があると思います。エンティティを追加して他のエンティティにリンクするだけで、両側で関係を作成する必要はありません。

カテゴリ エンティティ

/**
 * @ORM\Entity
 * @ORM\Table(name="task_categories")
 * @property int $id
 * @property string $name
 */
class Category
{
        /**
         * @ORM\Id
         * @ORM\Column(type="integer");
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;

        /**
         * @ORM\Column(type="string", nullable=false)
         */
        protected $name;
  ...
        /**
         * Setters and getters we need
         */
        public function getId()
        {
                return $this->id;
        }
        public function setId($id)
        {
        $this->id = (int) $id;
        }

        public function getName()
        {
                return $this->name;
        }
        public function setName($name)
        {
                $this->name = $name;
        }

}

ユーザー エンティティ:

/**
 * @ORM\Entity
 * @ORM\Table(name="users")
 */
class User implements UserInterface, ProviderInterface
{
        /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
    ...
        /**
         * @ORM\ManyToMany(targetEntity="ZDUser\Entity\Group")
         * @ORM\JoinTable(name="users_groups_linker",
         *        joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
         *        inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
         * )
         */
        protected $groups;

        /**
         * Initialies the object
         */
        public function __construct()
        {
                $this->groups = new ArrayCollection();
        }

        /* Getters and setters, we must define these for the implementation to work */
        public function getId()
        {
                return $this->id;
        }
        public function setId($id)
        {
                $this->id = (int) $id;
        }

        /* Get and add groups */
        public function getGroups()
        {
            return $this->groups;
        }
        public function addGroup(Group $group)
        {
            $this->groups->add($group);
        }

フォームコード:

class TaskForm extends Form implements ObjectManagerAwareInterface
{
        protected $objectmanager;

        public function __construct(EntityManager $em)
        {
                // we want to ignore the name passed
                parent::__construct('task');


                $this->setHydrator(new DoctrineHydrator($em,'TaskList\Entity\Task'));

                $this->setAttribute('method', 'post');
                $this->add(array(
                        'name' => 'id',
                        'attributes' => array(
                                'type'  => 'hidden',
                        ),
                ));

                $this->add(array(
                        'name' => 'subject',
                        'type'  => 'Text',
                        'options' => array(
                                'label' => 'Subject',
                        ),
                ));

                $this->add(array(
                        'name' => 'category',
                        'type' => 'DoctrineModule\Form\Element\ObjectSelect',
                        'options' => array(
                                'label' => "Category",
                                'object_manager' => $em,
                                'target_class' => 'TaskList\Entity\Category',
                                'property' => 'name',
                        ),
                ));


                $this->add(array(
                        'name' => 'assignedUsers',
                        'type' => 'DoctrineModule\Form\Element\ObjectSelect',
                        'attributes' => array(
                                'multiple' => 'multiple',
                        ),
                        'options' => array(
                                'label' => "Assigned To (User)",
                                'object_manager' => $em,
                                'target_class' => 'ZDUser\Entity\User',
                                'property' => 'email',
                        ),
                ));

編集と追加のコントローラー:

    public function addAction()
    {
            $this->addedit();

            // Grab form
            $form = new TaskForm($this->getEntityManager());

            // Grab any request we may have
            $request = $this->getRequest();

            // If it a post ...
            if ($request->isPost()) {
                    $task = new Task();
                    $form->bind($task);

                    // Populate data
                    $form->setData($request->getPost());

                    // Check if the form is valid
                    if ($form->isValid()) { 
                            // Setup some things we need
                            $task->setCreated(new \DateTime("now"));

                            // Save
                            $this->getEntityManager()->persist($task);
                            $this->getEntityManager()->flush();

                            // Redirect to list of tasks
                            return $this->redirect()->toRoute('tasklist'); 
                    }
            }

            return array(
                    'form' => $form
            );
    }


    public function editAction()
    {
            $this->addedit();

            // Get ID or redirect
            $id = (int)$this->getEvent()->getRouteMatch()->getParam('id');
            if (!$id) {
                    return $this->redirect()->toRoute('tasklist');
            }

            // Create a form
            $form = new TaskForm($this->getEntityManager());

            // Grab entity from doctrine
            $task = $this->getEntityManager()->find('TaskList\Entity\Task', $id);

            // Bind the form to the task 
            $form->bind($task);

            // Check if we have a request and if its POST
            $request = $this->getRequest();

            if ($request->isPost()) {
                    // If it is, set the form data from the request
                    $form->setData($request->getPost());

                    // If the form is valid, bind the values
                    if ($form->isValid()) {
                            // Setup some things we need
                            $task->setLastUpdated(new \DateTime("now"));

                            // Flush the update
                            $this->getEntityManager()->flush();

                            // Redirect to list of tasks
                            return $this->redirect()->toRoute('tasklist');
                    }
            }

            return array(
                    'id' => $id,
                    'form' => $form,
            );
    }

本当に単純なものが欠けていると確信しています。

4

2 に答える 2

0

おそらく正しい方法ではありませんか?私は自分のアイデアを彼らの ML に投稿しました :) おそらく正しい方法ではないでしょうか? 私は自分のアイデアを彼らのMLに投稿しました:)

diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
index cba525a..2f62375 100644
--- a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
+++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
@@ -667,7 +667,17 @@ class ClassMetadataInfo implements ClassMetadata
             return $id;
         }

-        $value = $this->reflFields[$this->identifier[0]]->getValue($entity);
+
+               /**
+                * NK: First try use the getter, in the case of a proxied object, the reflection is not going to work
+                * as the proxied object does not have any properties
+                */
+               $getter = 'get' . ucfirst($this->identifier[0]);
+               if (method_exists($entity, $getter)) {
+                       $value = $entity->$getter();
+               } else {
+               $value = $this->reflFields[$this->identifier[0]]->getValue($entity);
+               }
于 2013-06-14T12:37:07.143 に答える