编辑两个实体之间具有额外属性的关系n:m的表单


Editing form for relationship n:m with extra attributes between two entities

我有两个实体之间的映射:

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;
    }
}

当我编辑订单时,我应该能够添加/删除该订单上的产品,但我不知道如何实现这一点。我知道我必须使用表格集合,但如何使用呢?我的意思是一个集合应该嵌入如下:

$builder->add('product', 'collection', array(
    'type' => new OrderHasProductType(),
    'allow_add' => true,
    'allow_delete' => true
));

什么时候我应该创建一个新的OrderHasProductType表单,我想到目前为止我已经理解了,但我现在的问题是,订单的ID会发生什么?处理具有额外参数的关系n:m的嵌入形式的正确方法是什么?

有人能给我一些代码示例来整理我的想法吗?

额外资源

  • 订单实体完整来源
  • 产品实体完整来源
  • 订单表单类型完整来源
  • OrderHasProduct表单类型完整来源

我认为您的情况有点复杂,因为您与两个实体没有标准的多对多关系,而是与三个实体有两个单独的一对多和多对一关系。

通常,在完全多对多的情况下,流程将具有(例如)OrderType表单,该表单包含一个Collection字段,该字段包含表示分配给订单的产品的ProductTypes。

'allow_add' => true意味着如果Symfony看到一个没有ID的条目,它希望它是通过Javascript添加的全新条目,并乐于调用表单Valid并将新条目添加到实体中。'allow_delete' => true反过来意味着,如果其中一个条目丢失,Symfony将从实体中删除它。)

但是,您还有一个实体级别,即Order->OrderHasProduct->Product。因此,从逻辑上讲,您的OrderType表单包含OrderHasProductType表单的集合(如上所述),该集合又包含一个ProductType表单

所以你的订单类型变得更像这样:

$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
));

还有一种产品类型:

$builder->add('product', 'entity', array(
    'class' => 'ProductBundle:Product'
));

Symfony应该乐于将您的实体映射到正确的类型级别。在您的视图中,您需要包含Javascript,它将理解向订单添加产品也涉及ProductHasOrder级别-最好是放入一些数据,看看Symfony如何将其转化为一种形式,然后模仿Javascript中的结构。