2

任何人都有一个使用 ZF2 和 Doctrine 2 的多对多关系的完整示例,尤其是在使用 ObjectMultiCheckBox 时?我找到了本教程 - https://github.com/doctrine/DoctrineModule/blob/master/docs/hydrator.md但它没有解释如何进行多对多关系。

4

2 回答 2

0

K so I figured out how todo this eventually after realizing the hydrator wasn't binding associations and I had to create the link. I'm going to put a full blog post up explaining it but in case you're still stuck. If you want to look at all the code together I've got it up on github (link) mind you I'm actively learning/developing/cleaning it up so its a bit messy

Basically you need to collect the selected models, create the association link by adding them to the entity, then persist the entity WITH the cascade add/del active on Doctrine (or manually do it by persisting the link's before the entity).

Below example is a Many-to-Many between my Posts and Categories

You need to have cascade active on your entity's property

/**
 * @ORM\OneToMany(targetEntity="CategoryPostAssociation", mappedBy="category",  cascade={"persist", "remove"})
 */
protected $category_post_associations;

You need to push the object manager from your Form to your fieldsets

PostFieldSet

$categoryFieldset = new CategoryFieldset($objectManager);
    $this->add(array(
        'type'    => 'DoctrineModule\Form\Element\ObjectMultiCheckbox',
        'name' => 'categories',
        'options' => array(
            'label' => 'Select Categories',
            'object_manager' => $objectManager,
            'should_create_template' => true,
            'target_class'   => 'OmniBlog\Entity\Category',
            'property'       => 'title',
            'target_element' => $categoryFieldset,
          ),
    ));

and categoryfieldset just has a textbox of the Title.

In my PostController's AddAction

public function addAction() {
    // Get your ObjectManager
    $objectManager = $this->getEntityManager();

    //Create the form and inject the ObjectManager
    //Bind the entity to the form
    $form = new PostForm($objectManager);
    $post = new Post();
    $form->bind($post);

    $request = $this->getRequest();
    if ($request->isPost()) {
        $form->setData($request->getPost());

        if ($form->isValid()) {
            /*
            * Get IDs from form element
            * Get categories from the IDs
            * add entities to $post's categories list
            */
            $element = $form->getBaseFieldset()->get('categories'); //Object of: DoctrineModule\\Form\\Element\\ObjectMultiCheckbox
            $values = $element->getValue();

            foreach($values as $catID){
                $results = $objectManager->getRepository('OmniBlog\Entity\Category')->findBy(array('id' => $catID));
                $catEntity = array_pop($results);                   
                $link = $post->addCategory($catEntity);
                //Entity/Post 's association table cascades persists and removes so don't need to persist($link), but would be done here
            }

            $objectManager->persist($post);
            $objectManager->flush();

            return $this->redirect()->toRoute(
                static::ROUTE_CHILD,
                array('controller' => static::CONTROLLER_NAME
            ));
        }
    }
    return array('form' => $form);
}

Above if you see $post->addCategory($catEntity); this leads to my Entity or Model managing the linking (I was passing back the link encase I want to handle the cascading manually)

Post

    /**
 * Returns the created $link
 */
public function addCategory(Category $category){
    $link = new CategoryPostAssociation();
    $link->setCategory($category);
    $link->setPost($this);
    $this->addCategoryPostAssociations($link);
    return $link;
}
于 2013-12-07T03:58:56.780 回答
-1

找到了一个很好的博客,其中逐步解释了需要做什么 - http://laundry.unixslayer.pl/2013/zf2-quest-zendform-many-to-many/

于 2013-12-18T08:26:52.427 回答