我在两个实体之间有这种映射:
class Orders {
// Other attributes
/**
* @ORM\OneToMany(targetEntity="OrderHasProduct", mappedBy="order")
*/
protected $orderProducts;
// Other set/get methods
public function getOrderProducts()
{
return $this->orderProducts;
}
}
class Product {
// Other attributes
/**
* @ORM\OneToMany(targetEntity="\Tanane\FrontendBundle\Entity\OrderHasProduct", mappedBy="product")
*/
protected $orderProducts;
// Other set/get methods
public function getOrderProducts()
{
return $this->orderProducts;
}
}
当然,由于许多订单可以有很多产品,但还有一个额外的属性需要这个其他实体:
class OrderHasProduct
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="\Tanane\FrontendBundle\Entity\Orders")
* @ORM\JoinColumn(name="general_orders_id", referencedColumnName="id")
*/
protected $order;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="\Tanane\ProductBundle\Entity\Product")
* @ORM\JoinColumn(name="product_id", referencedColumnName="id")
*/
protected $product;
/**
* @ORM\Column(type="integer", nullable=false)
*/
protected $amount;
public function setOrder(\Tanane\FrontendBundle\Entity\Orders $order)
{
$this->order = $order;
}
public function getOrder()
{
return $this->order;
}
public function setProduct(\Tanane\ProductBundle\Entity\Product $product)
{
$this->product = $product;
}
public function getProduct()
{
return $this->product;
}
public function setAmount($amount)
{
$this->amount = $amount;
}
public function getAmount()
{
return $this->amount;
}
}
当我编辑订单时,我应该能够添加/删除该订单上的产品,但我不知道如何实现这一目标。我知道我必须使用form collection但是如何?我的意思是应该嵌入一个集合如下:
$builder->add('product', 'collection', array(
'type' => new OrderHasProductType(),
'allow_add' => true,
'allow_delete' => true
));
当我应该创建一个新的OrderHasProductType
表单时,我想我明白了,但现在我的问题是,订单的ID会发生什么变化?什么是处理嵌入形式的关系n:m与额外参数的正确方法?
可以给我一些代码示例来订购我的想法吗?
额外资源
答案 0 :(得分:1)
我认为你的情况有点复杂,因为没有与两个实体的标准Doctrine多对多关系,而是两个独立的一对多和多对一关系,有三个实体。
通常,对于完整的多对多,该过程将具有例如OrderType表单,其包含充满ProductTypes的Collection字段,该ProductTypes表示分配给Order的Products。
('allow_add' => true
表示如果Symfony看到一个没有ID的条目,它希望它是一个通过Javascript添加的全新项目,并且很乐意调用表单Valid并将新项目添加到实体。'allow_delete' => true
反过来意味着如果缺少其中一个项目,那么Symfony会将其从实体中删除。)
但是,您还有一个级别的实体,它会Order->OrderHasProduct->Product
。因此,逻辑上您的OrderType表单包含OrderHasProductType表单的集合(如上所述),而表单又包含ProductType表单。
所以你的OrderType变得更像这样:
$builder->add('orderHasProducts', 'collection', array(
'type' => new OrderHasProductType(),
'allow_add' => true,
'allow_delete' => true
));
您还有另一个级别的产品:
OrderHasProductType
$builder->add('product', 'collection', array(
'type' => new ProductType(),
'allow_add' => true,
'allow_delete' => true
));
还有ProductType:
$builder->add('product', 'entity', array(
'class' => 'ProductBundle:Product'
));
Symfony应该乐意将您的实体映射到正确的类型级别。在您的视图中,您需要包含Javascript,它将理解向订单添加产品还涉及ProductHasOrder级别 - 最好放入一些数据并查看Symfony如何将其转换为表单,然后模仿Javascript中的结构。