如何显示两个ManyToMany实体Symfony2

时间:2013-01-04 22:10:27

标签: symfony left-join entity-relationship

我在SF2.0.15下使用Doctrine2,我有两个实体。

-Expedition - 步骤

为了解释,一次探险可以有几个步骤,一步可以属于几次探险。此外,一次远征属于他的创始人(名为“所有者”并存储在用户实体中)。因此,我选择在Expedition和Steps表之间加入ManyToMany。在您看来,这是一个好的选择还是一个错误的选择?

我想创建一个方法,选择属于一次探险的所有步骤(我有探测的ID包含在$ id_exp中)。所以,我在互联网上阅读了很多主题,但它总是失败,我想知道为什么......

实体Expedition.php

/**
 * @ORM\ManyToOne(targetEntity="Easymuth\UserBundle\Entity\User")
 * @ORM\JoinColumn(nullable=false)
 */
private $owner;
/**
 * @ORM\ManyToMany(targetEntity="Easymuth\ExpeditionBundle\Entity\Step", cascade={"persist"})
 */
private $steps;

/**
 * Add steps
 *
 * @param Easymuth\ExpeditionBundle\Entity\Step $steps
 */
public function addStep(\Easymuth\ExpeditionBundle\Entity\Step $step)
{
    $this->steps[] = $step;
}

public function __construct()
{
    $this->steps = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
 * Get steps
 *
 * @return Doctrine\Common\Collections\Collection 
 */
public function getSteps()
{
    return $this->steps;
}

ExpeditionRepository.php:

namespace Easymuth\ExpeditionBundle\Entity;

use Doctrine\ORM\EntityRepository;

class ExpeditionRepository extends EntityRepository
{
public function getStepsFromExpedition($id_exp) {
  $qb = $this->createQueryBuilder('e')
             ->leftJoin('e.steps', 's')
             ->addSelect('s')
             ->where('e.id = :id')
             ->setParameter('id', $id_exp);

  return $qb->getQuery()->getResult();
}
}

最后在我的控制器中,我有:

namespace Easymuth\ExpeditionBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Easymuth\ExpeditionBundle\Entity\Expedition;

class MainController extends Controller
{
public function stepsAction($id_exp) {

    $expedition = $this->getDoctrine()
                    ->getEntityManager()
                    ->getRepository('EasymuthExpeditionBundle:Expedition')
                    ->getStepsFromExpedition($id_exp);

    print_r($expedition->getSteps()); // it displays a very long contents........

    //return $this->render('EasymuthExpeditionBundle:Main:steps.html.twig'));
   }
}

print_r(或var_dump)上显示的错误是:

Fatal error: Call to a member function getSteps() on a non-object in /Applications/MAMP/htdocs/easymuth/src/Easymuth/ExpeditionBundle/Controller/MainController.php

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:0)

这是一个不错的选择,你必须使用ManyToMany关联来实现这个设计,好点! 但是要小心,如果你想在你的关联中添加信息(例如顺序,对探险中的步骤有用),你必须创建一个新的实体。 查看here了解详情。

然后,问题出在您的控制器中。 (您的存储库中不需要其他功能)
如果你想从一次探险中获得所有步骤,只需在你的控制器中进行:

//find your expedition
$expedition = $this->getDoctrine()
                    ->getEntityManager()
                    ->getRepository('EasymuthExpeditionBundle:Expedition')
                    ->find($id_exp);

//then get the steps from this expedition
$steps = $expedition->getSteps();

您必须确保$id_exp 的探险确实存在,否则当您想要使用$expedition变量时会抛出错误(因为它设置为null) 你可以这样检查存在:

if(!$expedition) {
    //do some stuff like throwing exception
}