首先我要问一个类似的问题并得到答案。我尝试在这里使用这些原则,但我再次陷入困境,我不知道从哪里开始。
我有一个页面,其中列出了所有'产品'以及他们尊重的ID,价格和名称。在同一页面上,我想获得我为每个人创建的描述。描述是它自己的实体,并拥有它自己的控制器。
在ProductController
我的indexAction
内,我试图让说明出现在这里。
问题是,我没有在indexAction
内引用ID(我使用findAll)。我尝试使用$key
遍历所有产品和参考,但我要么在说明中输入最新描述,要么现在:
错误:在非对象上调用成员函数getDescriptions()。
编辑:我应该提到$ prodEnt为null ...
我不想来这里寻求帮助,但我对如何获得我想要的东西没有更多的想法。
以下为ProductController
indexAction
:
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 :(得分:2)
你的情况过于复杂。当您检索所有产品实体时,除了在响应中返回这些实体之外,您不需要执行任何其他操作。每个实体在类定义中都已将其描述与其关联。此外,在典型的索引操作中,如果不存在产品,则不一定需要抛出异常...您可能仍希望向用户显示索引页,然后如果没有任何产品,他们只会看到一张空桌子。您的indexAction()
只能是:
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('PasShopTestBundle:Product')->findAll();
return array(
'entities' => $entities,
);
}
你的Twig也会在单个产品有多个描述的瞬间出现问题,因为<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();
}
然后,您可以为Twig执行以下操作:
{% for description in entity.descriptions %}
{{ description }}{% if not loop.last %}, {% endif %}
{% endfor %}
答案 1 :(得分:1)
我使用另一个答案来放置格式化的代码。
如果您拥有所有产品,且关系正确,则只需循环使用它们。
foreach ($entities as $entity) {
// To get the descriptions...
$entity->getDescriptions();
}
顺便说一句,你的代码非常非常奇怪。首先,您要检索所有产品,然后在这个产品的循环中,您将再次检索每个产品并获取其描述。你不在乎的是:
在你的控制器中:
$entities
正在存储所有产品。
$entity
始终是最后一个产品,它在循环中定义
$descriptions
始终来自最后一个产品
现在您将这些变量发送到您的视图。
在您看来:
您正在使用entities
进行循环并将其声明为entity
,这会覆盖您在控制器中传递的entity
。顺便说一下,传递$entity
和$descriptions
是不必要的,你正在使用entities
进行循环,只需循环获取这些信息。
答案 2 :(得分: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;