需要帮助从ManyToOne获得OneToMany关联


Need help getting OneToMany association from ManyToOne

让我先说我以前问过一个类似的问题并得到了答案。我尝试在这里使用这些原则,但我再次陷入困境,不确定从这里开始。

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

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

问题是,我没有在indexAction中引用id(我使用findAll(。我尝试使用$key遍历所有产品和参考,但我要么获得描述中输入的最新描述,要么当前:

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

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

不想来这里寻求帮助,但我不再想如何得到我想要的东西。

以下是indexAction ProductController

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;

任何帮助真的非常感谢,谢谢!

你把情况复杂化了。 检索所有产品实体时,除了在响应中返回这些实体外,无需执行任何其他操作。 每个实体在类定义中都已具有与其关联的说明。 此外,在典型的索引操作中,如果不存在产品,则不一定需要引发异常...您可能仍然希望向用户显示索引页,然后如果没有任何产品,他们只会看到一个空表。 您的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 %}

示例给出了一个以逗号分隔的说明列表,但您可以根据需要更改该循环。 此外,还可以向Description实体添加__toString()方法,以避免直接调用该productDescription字段:

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

然后,这将允许您为树枝执行以下操作:

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

我使用另一个答案来放置格式化的代码。

如果你拥有所有产品,并且关系是正确的,你只需循环使用它们。

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

顺便说一下,你的代码非常非常奇怪。首先,您将检索所有产品,然后,在此产品循环中,您将再次检索每个产品并获取其描述。你不在乎的是:

在控制器中:

$entities存储所有产品。

$entity始终是最后一个产品,它是在循环中定义的

$descriptions总是来自上一个产品

现在,您将这些变量发送到您的视图。

在您看来:

您正在对entities执行循环并将它们声明为 entity ,这将覆盖您在控制器中传递entity。顺便说一下,传递$entity$descriptions查看是不必要的,您正在使用entities进行循环,只需循环获取这些信息即可。

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

在产品实体中,您必须设置从关系中提取级别。

修复你们的关系:

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;