2016-02-12 39 views
4

让我先说我之前问过类似的问题,并得到了答案。我尝试在这里使用这些原则,但我再次被卡住了,我不知道该从哪里出发。需要帮助从ManyToOne获取OneToMany关联

我有一个页面,列出所有'产品'以及他们尊敬的编号,价格和名称。在这个相同的页面上,我想获得我为他们创建的描述。说明是它自己的实体,并有它自己的控制器。

在我的ProductController中,在我的indexAction中,我试图让描述出现在这里。

问题是,我没有在indexAction(我使用findAll)中引用一个id。我试图通过使用$key来遍历所有产品和参考,但我可以获取描述中或当前输入的最近描述:

错误:在非对象上调用成员函数getDescriptions()。

编辑:我应该提到$ prodEnt为空...

我不希望到这里来寻求帮助,但我对如何去获得我想要的东西没有更多的想法。

这里是ProductControllerindexAction

namespace Pas\ShopTestBundle\Controller; 

use Symfony\Component\HttpFoundation\Request; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; 
use Pas\ShopTestBundle\Entity\Product; 
use Pas\ShopTestBundle\Form\ProductType; 

/** 
* Product controller. 
* 
* @Route("/product") 
*/ 
class ProductController extends Controller 
{ 
    /** 
    * Lists all Product entities. 
    * 
    * @Route("/", name="product") 
    * @Method("GET") 
    * @Template() 
    */ 
    public function indexAction() 
    { 
     $em = $this->getDoctrine()->getManager(); 

     $entities = $em->getRepository('PasShopTestBundle:Product')->findAll(); 

     //$entities = $em->getRepository('PasShopTestBundle:Product')->find($id); 
     //var_dump($entities); 
     //dump($entities); die; 

     if (!$entities) { 
      throw $this->createNotFoundException('Error Nothing in Entities.'); 
     } 
     else { 
      //dump($entities); die; 
      foreach ($entities as $key => $entity) { 
       //dump($entities); die; 
       //dump($entity); die; 
       //dump($key); die; //needs to be 1 
       //$entity = $em->getRepository('PasShopTestBundle:Product')->findAll($key); 
       $prodEnt = $em->getRepository('PasShopTestBundle:Product')->find($key); 
       //dump($entity); die; 
       //dump($prodEnt); die; 
       $descriptions = $prodEnt->getDescriptions(); 
       //dump($entity); die; 
      } 
      //dump($entities); die; 
     } 

     return array(
      'descriptions' => $descriptions, 
      'entities' => $entities, 
      'entity' => $entity, 
     ); 
    } 

这里是indexAction思想路线树枝文件:

{% extends '::base.html.twig' %} 

{% block body -%} 
    <h1>Product List</h1> 

    <table class="records_list"> 
     <thead> 
      <tr> 
       <th>Id</th> 
       <th>Name</th> 
       <th>Price</th> 
       <th>Quantity</th> 
       <th>Description</th> 
       <th>Actions</th> 
      </tr> 
     </thead> 
     <tbody> 
     {% for entity in entities %} 
      <tr> 
       <td><a href="{{ path('product_show', { 'id': entity.id }) }}">{{ entity.id }}</a></td> 
       <td>{{ entity.name }}</td> 
       <td>{{ entity.price }}</td> 
       <td>{{ entity.quantity }}</td> 

       {% for key, entity in descriptions %} 

        <pre>{{ dump(entity) }}</pre> 

        {# <pre>{{ dump(key) }}</pre> #} 

         <td>{{ entity.productDesciption }}</td> 

        <pre>{{ dump(entity.productDesciption) }}</pre> 

       {% endfor %} 

       <td> 
        <ul> 
         <li> 
          <a href="{{ path('product_cart', { 'id': entity.id }) }}">Add Product To Cart</a> 
         </li> 
         <li> 
          <a href="{{ path('product_show', { 'id': entity.id }) }}">show</a> 
         </li> 
         <li> 
          <a href="{{ path('product_edit', { 'id': entity.id }) }}">edit</a> 
         </li> 
        </ul> 
       </td> 
      </tr> 
     {% endfor %} 
     </tbody> 
    </table> 

     <ul> 
     <li> 
      <a href="{{ path('product_new') }}"> 
       Create a new entry 
      </a> 
     </li> 
    </ul> 
    {% endblock %} 

产品实体:

namespace Pas\ShopTestBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\ArrayCollection; 

/** 
* Product 
* 
* @ORM\Table(name="products") 
* @ORM\Entity(repositoryClass="Pas\ShopTestBundle\Entity\ProductRepository") 
*/ 
class Product 
{ 
    /** 
    * @var ArrayCollection 
    * 
    * @ORM\OneToMany(targetEntity="Description", mappedBy="product") 
    */ 
    private $descriptions; 

描述实体:

namespace Pas\ShopTestBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collection\ArrayCollection; 

/** 
* Description 
* 
* @ORM\Table(name="descriptions") 
* @ORM\Entity(repositoryClass="Pas\ShopTestBundle\Entity\DescriptionRepository") 
*/ 
class Description 
{ 
    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string") 
    */ 
    private $productDescription; 

    /** 
    * @var Product 
    * 
    * @ORM\ManyToOne(targetEntity="Product", inversedBy="descriptions") 
    * @ORM\JoinColumn(name="product_id", referencedColumnName="id") 
    */ 
    private $product; 

任何帮助真的很感激,谢谢!

+0

所以有可以是单个产品的多个描述,是的?这就是你想要展示的东西? –

+0

是的,可能会有。目前的情况是,现在每个产品只有一个说明,以便只说明会显示 –

回答

2

您这样的情况过于复杂。当您检索所有产品实体时,除了在回复中返回这些实体外,您无需执行其他任何操作。每个实体在您的类定义中已经有与其相关的描述。此外,在典型的索引操作中,如果没有产品存在,则不一定需要抛出异常...您可能仍然想向用户显示索引页,然后如果没有任何产品,他们只会看到一个空的表。您indexAction()可以简单地是:

public function indexAction() 
{ 
    $em = $this->getDoctrine()->getManager(); 

    $entities = $em->getRepository('PasShopTestBundle:Product')->findAll(); 

    return array(
     'entities' => $entities, 
    ); 
} 

你的枝杈也将导致问题的单品有一个以上描述的瞬间,因为<td>细胞的数量将是每行变量。这将是更好的做这样的事情显示以逗号分隔的描述列表,或者由<br><p>分离,或者你甚至可以通过<ul><li>使他们的无序列表:

{% for entity in entities %} 
    <tr> 
     <td><a href="{{ path('product_show', { 'id': entity.id }) }}">{{ entity.id }}</a></td> 
     <td>{{ entity.name }}</td> 
     <td>{{ entity.price }}</td> 
     <td>{{ entity.quantity }}</td> 

     {% for description in entity.descriptions %} 
      {{ description.productDescription }}{% if not loop.last %}, {% endif %} 
     {% endfor %} 
     {# ... #} 
    </tr> 
{% endfor %} 

这个例子给出了一个逗号分隔的描述列表,但你可以改变那个循环,但你认为合适。此外,您还可以添加一个__toString()方法您Description实体,以避免调用该productDescription场直接:

// class Description 
public function __toString() 
{ 
    return $this->getProductDescription(); 
} 

那么这将让你做你的嫩枝如下:

{% for description in entity.descriptions %} 
    {{ description }}{% if not loop.last %}, {% endif %} 
{% endfor %} 
+0

感谢您的帮助和建议!然而,你的解决方案给我这个错误:在src/Pascal/ShopTestBundle/C++中渲染模板期间抛出异常(“可捕获的致命错误:类Pascal \ ShopTestBundle \ Entity \ Description的对象无法转换为字符串”资源/ views/Product/index.html.twig在第26行。(第26行是第二个描述的地方)说我的描述必须是数组而不是字符串? –

+0

你想要显示的'Description'实体上的字段的名称是什么?您将需要直接引用('description.name'或其他),或者在'Description'上添加一个'__toString()'方法来返回该值。如果你用这个字段更新你的描述实体,我可以更新我的答案。 –

+0

我明白了,再次感谢你。您帮我了解了更多 –

0

可能您正在使用单元化对象,尝试设置获取级别。

在您的产品实体中,您必须根据关系设置获取级别。

解决您的关系:

namespace Pas\ShopTestBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\ArrayCollection; 

/** 
* Product 
* 
* @ORM\Table(name="products") 
* @ORM\Entity(repositoryClass="Pas\ShopTestBundle\Entity\ProductRepository") 
*/ 
class Product 
{ 
    /** 
    * @var ArrayCollection 
    * 
    * @ORM\OneToMany(targetEntity="Description", mappedBy="product", fetch="EAGER") 
    */ 
    private $descriptions; 
+0

仍然得到错误:错误:调用一个成员函数getDescriptions()非对象 –

+0

通过读取错误:*错误:调用一个成员函数getDescriptions()在一个非对象*我认为该对象似乎没有找到。 –

+0

我在代码中看到一个奇怪的部分。您正在检索所有产品并在结果循环中再次检索数据库? –

1

我用另一种答案把一个格式化的代码。

如果您拥有所有产品,并且关系正确,那么您只需在循环中使用它们。

foreach ($entities as $entity) { 
    // To get the descriptions... 
    $entity->getDescriptions(); 
} 

顺便说一下你的代码非常非常奇怪。首先,您在检索所有产品之后,再次检索每种产品并获取其描述。什么,你不关心是:

在你的控制器:

$entities被存储的所有产品。

$entity始终将最后一个产品,它在环

$descriptions定义永远是从过去的产品

现在你把这些变量视图。

您认为:

你正在做一个循环与entities并宣布他们为entity,这个覆盖entity你的控制器通过。顺便说通过$entity$descriptions查看是不必要的,你与entities做循环,刚刚获得在循环这些信息。

+0

在视图中,您是正确的:我以前有{%for key,description in description%}并使用描述变量。我现在就把它解决了。至于检索产品两次,我这样做是因为我需要一种方法来获取单个产品,因此$实体而不是$实体。 –

+0

好的,但是在$实体中,你正在把一个循环对吗?在此循环中,您每次都有单独的产品。 –