dqcd84732 2015-07-19 08:11
浏览 42
已采纳

Symfony 2,从多对多的关联中获取实体

I have entity Product and Tires. One Product has more Tires and one Tire can be on more Products.

In my controller when I call

$product = $em->getRepository('MyBundle:Product')->find($id);

or

$tires = $product->getExtraTires();

Related Tires won't return.

/**
 * Product
 *
 * @ORM\Table(name="product")
 * @ORM\Entity
 */

class Product {

    public function __construct()
    {
        $this->extraTires = new ArrayCollection();
    }

   /**
     * @ORM\ManyToMany(targetEntity="Tires", mappedBy="products")
     * @ORM\JoinTable(name="product_tires",
     *       joinColumns={@ORM\JoinColumn(name="product_id", referencedColumnName="id")},
     *       inverseJoinColumns={@ORM\JoinColumn(name="tires_id", referencedColumnName="id")})
     */
    private $extraTires;

   /**
     * Get extraTires
     *
     * @return ArrayCollection
     */
     public function getExtraTires()
     {
         return $this->extraTires;
     }

    /**
      * Add extraTires
      *
      * @param Tires $extraTires
      * @return Product
      */

      public function addExtraTire(Tires $extraTires)
      {
          $this->extraTires[] = $extraTires;

          return $this;
      }

     /**
      * Remove extraTires
      *
      * @param \Wielton\WieltonBundle\Entity\Tires $extraTires
      */
      public function removeExtraTire(Tires $extraTires)
      {
          $this->extraTires->removeElement($extraTires);
      }

And my Tires entity

/**
 * Tires
 *
 * @ORM\Table(name="Tires")
 * @ORM\Entity
 */    
class Tires {

    public function __construct()
    {
        $this->products = new ArrayCollection();
    }

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
     private $id;

    /**
     * @ORM\ManyToMany(targetEntity="Product", inversedBy="extraTires")
     * @ORM\JoinTable(name="product_tires",
     *       joinColumns={@ORM\JoinColumn(name="tires_id", referencedColumnName="id")},
     *       inverseJoinColumns={@ORM\JoinColumn(name="product_id", referencedColumnName="id")})
     */
     private $products;

    /**
     * Add products
     *
     * @param Product $products
     * @return Tires
     */
     public function addProduct(Product $products)
    {
        $this->products[] = $products;

        return $this;
    }

    /**
     * Remove products
     *
     * @param Product $products
     */
     public function removeProduct(Product $products)
    {
        $this->products->removeElement($products);
    }

    /**
     * Get products
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
     public function getProducts()
     {
        return $this->products;
     }

I designed entities according doctrine doctumentation. When I add Product and choose tires to add everything looks ok in join table.

What am I missing?

EDIT

I found something, but I don't fully understand how does it work :)

In my controller when Im getting Product entity with

$product = $em->getRepository('MyBundle:Product')->find($id);

I have to go in twig into product.extraTires.owner.extraTires And then I can see my associated tires here. And suddenly I have one more query to the database. So somehow I'm not calling it in controller properly.

SOLUTION Seems like query in controller wasn't complete. $tires now return array of tires, you can also use ->getValues() method.

$product = $em->getRepository('MyBundle:Product')->find($id);
$tires = $product->getExtraTires()->toArray();
  • 写回答

1条回答 默认 最新

  • doutui2883 2015-07-19 12:58
    关注

    Doctrine will not update automatically the in-memory hydrated object. The in-memory PHP object will not contain updated relation until you hydrate it again from the database or you update the in-memory representation yourself.

    Try to modify adders like the following (I let you look how to do that for the removers but it's the same idea):

    Product:

    class Product
    {
    
        public function addExtraTire(Tires $extraTires)
        {
            $this->extraTires[] = $extraTires;
    
            if (!$extraTires->getProducts()->contains($this) {
                $extraTires->addProduct($this);
            }
    
            return $this;
        }
    }
    

    Tires:

    class Tires
    {
        public function addProduct(Product $products)
        {
                $this->products[] = $products;
    
                if (!$products->getExtraTires()->contains($this) {
                    $products->addExtraTire($this);
                }
    
                return $this;
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Qt下使用tcp获取数据的详细操作
  • ¥15 idea右下角设置编码是灰色的
  • ¥15 全志H618ROM新增分区
  • ¥15 在grasshopper里DrawViewportWires更改预览后,禁用电池仍然显示
  • ¥15 NAO机器人的录音程序保存问题
  • ¥15 C#读写EXCEL文件,不同编译
  • ¥15 MapReduce结果输出到HBase,一直连接不上MySQL
  • ¥15 扩散模型sd.webui使用时报错“Nonetype”
  • ¥15 stm32流水灯+呼吸灯+外部中断按键
  • ¥15 将二维数组,按照假设的规定,如0/1/0 == "4",把对应列位置写成一个字符并打印输出该字符