Forms 表格symfony 2多个自参考实体

Forms 表格symfony 2多个自参考实体,forms,symfony,collections,self-reference,Forms,Symfony,Collections,Self Reference,我想创建一个包含自引用实体集合的表单 我需要一个表单来创建新产品,此表单将有一个包含现有产品的选择字段(子项) 我有一个产品实体,这个实体包含一个子字段(子字段也是一个产品) 产品实体: /** * @var integer * * @ORM\Column(name="id", type="bigint", length=20) * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @va

我想创建一个包含自引用实体集合的表单

我需要一个表单来创建新产品,此表单将有一个包含现有产品的选择字段(子项)

我有一个产品实体,这个实体包含一个子字段(子字段也是一个产品)

产品实体:

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

/**
 * @var string
 *
 * @ORM\Column(name="title", type="string", length=255)
 */
protected $title;

/**
 * @var string
 *
 * @ORM\Column(name="manufacturer_reference", type="string", length=255, nullable=true)
 */
protected $manufacturer_reference;

/**
 * @var string
 *
 * @ORM\Column(name="resume", type="text", nullable=true)
 */
protected $resume;

/**
 * @var boolean
 *
 * @ORM\Column(name="is_salable", type="boolean", options={"default" = 1})
 */
protected $is_salable = 1;

/**
 * @var boolean
 *
 * @ORM\Column(name="is_active", type="boolean", options={"default" = 1})
 */
protected $is_active = 1;

/**
 * @ORM\ManyToOne(targetEntity="\Hexanet\Common\CatalogBundle\Entity\ProductCategory")
 * @ORM\JoinColumn(name="product_category_id", referencedColumnName="id", nullable=true)
 */
protected $product_category;

/**
 * @ORM\ManyToOne(targetEntity="\Hexanet\Common\CatalogBundle\Entity\Manufacturer")
 * @ORM\JoinColumn(name="manufacturer_id", referencedColumnName="id", nullable=true)
 */
protected $manufacturer;

/**
 * @ORM\ManyToMany(targetEntity="\Hexanet\Common\CatalogBundle\Entity\Product", mappedBy="parents" )
 */
protected $children;

/**
 * @ORM\ManyToMany(targetEntity="\Hexanet\Common\CatalogBundle\Entity\Product")
 * @ORM\JoinTable(name="product_to_product",
 *     joinColumns={@ORM\JoinColumn(name="child_product_id", referencedColumnName="id")},
 *     inverseJoinColumns={@ORM\JoinColumn(name="parent_product_id", referencedColumnName="id")}
 * )
 */
protected $parents;

/**
 * @ORM\OneToMany(targetEntity="\Hexanet\Common\CatalogBundle\Entity\ProductPrice", mappedBy="product" )
 */
protected $product_prices;

/**
 * @ORM\OneToMany(targetEntity="\Hexanet\Common\CatalogBundle\Entity\ProductPricePurchase", mappedBy="product")
 */
protected $product_prices_purchase;

/**
 * @ORM\OneToMany(targetEntity="\Hexanet\Common\CatalogBundle\Entity\ProductPriceCustom", mappedBy="product")
 */
protected $product_prices_custom;

/**
 * Get id
 *
 * @return integer
 */
public function getId()
{
    return $this->id;
}

/**
 * Set title
 *
 * @param string $title
 * @return Product
 */
public function setTitle($title)
{
    $this->title = $title;

    return $this;
}

/**
 * Get title
 *
 * @return string
 */
public function getTitle()
{
    return $this->title;
}

/**
 * Set product category
 *
 * @param \Hexanet\Common\CatalogBundle\Entity\ProductCategory $product_category
 * @return Product
 */
public function setProductCategory(\Hexanet\Common\CatalogBundle\Entity\ProductCategory $product_category = null)
{
    $this->product_category = $product_category;

    return $this;
}

/**
 * Get product category
 *
 * @return \Hexanet\Common\CatalogBundle\Entity\ProductCategory
 */
public function getProductCategory()
{
    return $this->product_category;
}

/**
 * Set resume
 *
 * @param string $resume
 * @return Product
 */
public function setResume($resume)
{
    $this->resume = $resume;

    return $this;
}

/**
 * Get resume
 *
 * @return string
 */
public function getResume()
{
    return $this->resume;
}

/**
 * Set manufacturer reference
 *
 * @param string $title
 * @return Product
 */
public function setManufacturerReference($ref)
{
    $this->manufacturer_reference = $ref;

    return $this;
}

/**
 * Get manufacturer reference
 *
 * @return string
 */
public function getManufacturerReference()
{
    return $this->manufacturer_reference;
}

/**
 * Set is salable
 *
 * @param boolean $active
 * @return Product
 */
public function setIsSalable($salable)
{
    $this->is_salable = $salable;

    return $this;
}

/**
 * Get is salable
 *
 * @return boolean
 */
public function getIsSalable()
{
    return $this->is_salable;
}

/**
 * Set is active
 *
 * @param boolean $active
 * @return Product
 */
public function setIsActive($active)
{
    $this->is_active = $active;

    return $this;
}

/**
 * Get is active
 *
 * @return boolean
 */
public function getIsActive()
{
    return $this->is_active;
}

/**
 * Set manufacturer
 *
 * @param $manufacturer
 * @return Product
 */
public function setManufacturer($manufacturer)
{
    $this->manufacturer = $manufacturer;

    return $this;
}

/**
 * Get manufacturer
 *
 */
public function getManufacturer()
{
    return $this->manufacturer;
}

/**
 * Constructor
 */
public function __construct()
{
    $this->parents = new \Doctrine\Common\Collections\ArrayCollection();
    $this->children = new \Doctrine\Common\Collections\ArrayCollection();
    $this->product_prices = new \Doctrine\Common\Collections\ArrayCollection();
    $this->product_prices_purchase = new \Doctrine\Common\Collections\ArrayCollection();
    $this->product_prices_custom = new \Doctrine\Common\Collections\ArrayCollection();
}

/**
 * Add child
 *
 * @param \Hexanet\Common\CatalogBundle\Entity\Product $product
 * @return Product
 */
public function addChild(\Hexanet\Common\CatalogBundle\Entity\Product $product)
{
    die(var_dump($product));
    $this->children[] = $product;

    return $this;
}

/**
 * Remove child
 *
 * @param \Hexanet\Common\CatalogBundle\Entity\Product $product
 */
public function removeChild(\Hexanet\Common\CatalogBundle\Entity\Product $product)
{
    $this->children->removeElement($product);
}

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

/**
 * Add parent
 *
 * @param \Hexanet\Common\CatalogBundle\Entity\Product $product
 * @return Product
 */
public function addParent(\Hexanet\Common\CatalogBundle\Entity\Product $product)
{
    $this->parents[] = $product;

    return $this;
}

/**
 * Remove parent
 *
 * @param \Hexanet\Common\CatalogBundle\Entity\Product $price
 */
public function removeParent(\Hexanet\Common\CatalogBundle\Entity\Product $product)
{
    $this->parents->removeElement($product);
}

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

/**
 * Add product price
 *
 * @param \Hexanet\Common\CatalogBundle\Entity\ProductPrice $price
 * @return Product
 */
public function addProductPrice(\Hexanet\Common\CatalogBundle\Entity\ProductPrice $price)
{
    $this->product_prices[] = $price;

    return $this;
}

/**
 * Remove product price
 *
 * @param \Hexanet\Common\CatalogBundle\Entity\ProductPrice $price
 */
public function removeProductPrice(\Hexanet\Common\CatalogBundle\Entity\ProductPrice $price)
{
    $this->product_prices->removeElement($price);
}

/**
 * Get product prices
 *
 * @return \Doctrine\Common\Collections\Collection
 */
public function getProductPrices()
{
    return $this->product_prices;
}

/**
 * Add product price purchase
 *
 * @param \Hexanet\Common\CatalogBundle\Entity\ProductPricePurchase $price
 * @return Product
 */
public function addProductPricePurchase(\Hexanet\Common\CatalogBundle\Entity\ProductPricePurchase $price)
{
    $this->product_prices_purchase[] = $price;

    return $this;
}

/**
 * Remove product price purchase
 *
 * @param \Hexanet\Common\CatalogBundle\Entity\ProductPricePurchase $price
 */
public function removeProductPricePurchase(\Hexanet\Common\CatalogBundle\Entity\ProductPricePurchase $price)
{
    $this->product_prices_purchase->removeElement($price);
}

/**
 * Get product prices purchase
 *
 * @return \Doctrine\Common\Collections\Collection
 */
public function getProductPricesPurchase()
{
    return $this->product_prices_purchase;
}

/**
 * Add product price custom
 *
 * @param \Hexanet\Common\CatalogBundle\Entity\ProductPriceCustom $price
 * @return Product
 */
public function addProductPriceCustom(\Hexanet\Common\CatalogBundle\Entity\ProductPriceCustom $price)
{
    $this->product_prices_custom[] = $price;

    return $this;
}

/**
 * Remove product price custom
 *
 * @param \Hexanet\Common\CatalogBundle\Entity\ProductPriceCustom $price
 */
public function removeProductPriceCustom(\Hexanet\Common\CatalogBundle\Entity\ProductPriceCustom $price)
{
    $this->product_prices_custom->removeElement($price);
}

/**
 * Get product prices custom
 *
 * @return \Doctrine\Common\Collections\Collection
 */
public function getProductPricesCustom()
{
    return $this->product_prices_custom;
}}
对于表格,我有以下内容:

class ProductType extends AbstractType{

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('title')
        ->add('manufacturer_reference')
        ->add('resume')
        ->add('product_category', 'entity', array(
        'class' => 'HexanetCatalogBundle:ProductCategory',
        'property' => 'title',
        ))
        ->add('children', 'collection', array(
        'type' => new ProductChildrenType,
        'allow_add' => true));
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Hexanet\Common\CatalogBundle\Entity\Product'
    ));
}

public function getName()
{
    return 'hexanet_common_catalogbundle_producttype';
}}
问题是,我不知道如何创建ProductChildrenType生成器:

class ProductChildrenType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('product', 'entity', array(
        'class' => 'HexanetCatalogBundle:Product',
        'property' => 'title',
        ));
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Hexanet\Common\CatalogBundle\Entity\Product'
    ));
}

public function getName()
{
    return 'hexanet_common_catalogbundle_productchildrentype';
}}
->添加('product','entity',…)我有错误:

类“Hexanet\Common\CatalogBundle\Entity\product”中既不存在属性“product”,也不存在方法“getProduct()”或方法“isProduct()”


Thx的帮助

我有一个类似的商店案例,所以我可以在管理区添加额外的产品,这样我就可以在结账时提供它们。。。 我的同事和我昨天解决了这个问题,所以如果你仍然感兴趣,我们开始。。。。 我们使用的是Symfony 2.6.x,我还没有在较旧版本的Symfony上进行测试

->add('myExtras', 'collection', array(
            'type' => 'entity',
            'options' => array(
                'class'       => 'StoreBundle:Productos',
                'placeholder' => '-- Select an extra product --',
                'property' => 'name',
                'query_builder' => function (EntityRepository $er) use( $options ) {
                    return $er->createQueryBuilder('p')
                        ->where('p.asociable = :asociable')
                        ->andWhere('p.id != :selfid')
                        ->setParameters( array('adjuntable' => '1', 'selfid' => $options['selfid'] ));
                },
                'label' => 'Extra Product'
            ),
            'by_reference' => false,
            'allow_add'    => true,
            'allow_delete' => true
        ))
我们没有为“children”使用表单类型的集合,而是使用类型为“entity”的集合,并使用querybuilder来控制获得要显示的正确选项所需的条件

使用这个,我们停止了你收到的信息。。。为了保存和删除关系,当我们添加子项时,我们必须告诉子项设置父项。。。要删除相同的内容,请先告诉孩子们从家长列表中删除家长,然后再从孩子列表中删除孩子。。。(在代码中更容易看到)

在实体中,我必须收集myExtras(儿童)和imExtraOf(父母),因此在添加儿童时,我必须告诉儿童我正在接收对应的->addImExtraOf(我是您的父亲功能)。。。然后我们将产品添加到额外列表中。对于删除,同样,我们称之为first->removiemextraof,如果不这样做,关系将不会保存

实体:

public function addMyExtra(Productos $extra)
{
    $extra->addImExtraOf($this);
    if( !$this->myExtras->contains($extra) ) {
        $this->myExtras[] = $extra;
    }


    return $this;
}

public function removeMyExtra(Productos $extra)
{
    $extra->removeImExtraOf($this);
    $this->myExtras->removeElement($extra);
}
orm映射(yml):(myExtras=children,imExtraOf=parents)


希望它能帮助别人。

我认为错误很明显:您必须在
ProductChildrenType
中使用
product\u category
而不是
product
->添加('product\u category',…)
。希望能帮上忙不,我要的是产品选择列表,而不是类别。Product_类别在ProductType类中您找到解决方案了吗?我有一个非常相似的实体,我被困在同一点上。
manyToMany:        
    myExtras:
        targetEntity: Productos
        cascade: [ persist ]
        mappedBy: imExtraOf
        inversedBy: null  
        joinTable:
            name: productos_has_productos
            joinColumns:
                -
                    name: extra_id
                    referencedColumnName: id
            inverseJoinColumns:
                -
                    name: base_id
                    referencedColumnName: id
        orderBy: null
    imExtraOf:
        targetEntity: Productos
        cascade: [ persist ]
        mappedBy: null
        inversedBy: myExtras  
        joinTable:
            name: productos_has_productos
            joinColumns:
                -
                    name: base_id
                    referencedColumnName: id
            inverseJoinColumns:
                -
                    name: extra_id
                    referencedColumnName: id
        orderBy: null