2016-02-12 23 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

好的,但是在$實體中,你正在把一個循環對嗎?在此循環中,您每次都有單獨的產品。 –