我正在使用一个表格来处理与额外参数(额外字段/列)的N:M关系。这就是我到目前为止所做的事情:
以OrdersType.php
形式:
class OrdersType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
// $builder fields
// $builder fields only need on edit form not in create
if ($options['curr_action'] !== NULL)
{
$builder
// other $builder fields
->add("orderProducts", "collection", array(
'type' => new OrdersHasProductType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false
));
}
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Tanane\FrontendBundle\Entity\Orders',
'render_fieldset' => FALSE,
'show_legend' => FALSE,
'intention' => 'orders_form',
'curr_action' => NULL
));
}
public function getName()
{
return 'orders';
}
}
在OrderHasProductType.php
:
class OrdersHasProductType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('product', 'text', array(
'required' => FALSE,
'label' => FALSE
))
->add('amount', 'text', array(
'required' => TRUE,
'label' => FALSE
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Tanane\FrontendBundle\Entity\OrderHasProduct',
'intention' => 'order_has_product'
));
}
public function getName()
{
return 'order_has_product';
}
}
最后这是Orders.php
和OrdersHasProduct.php
个实体:
class Orders {
use IdentifiedAutogeneratedEntityTrait;
// rest of fields for the entity
/**
* @ORM\OneToMany(targetEntity="OrderHasProduct", mappedBy="order", cascade={"all"})
*/
protected $orderProducts;
protected $products;
/**
* @ORM\Column(name="deletedAt", type="datetime", nullable=true)
*/
protected $deletedAt;
public function __construct()
{
$this->orderProducts = new ArrayCollection();
$this->products = new ArrayCollection();
}
public function getOrderProducts()
{
return $this->orderProducts;
}
public function getDeletedAt()
{
return $this->deletedAt;
}
public function setDeletedAt($deletedAt)
{
$this->deletedAt = $deletedAt;
}
public function getProduct()
{
$products = new ArrayCollection();
foreach ($this->orderProducts as $op)
{
$products[] = $op->getProduct();
}
return $products;
}
public function setProduct($products)
{
foreach ($products as $p)
{
$ohp = new OrderHasProduct();
$ohp->setOrder($this);
$ohp->setProduct($p);
$this->addPo($ohp);
}
}
public function getOrder()
{
return $this;
}
public function addPo($ProductOrder)
{
$this->orderProducts[] = $ProductOrder;
}
public function removePo($ProductOrder)
{
return $this->orderProducts->removeElement($ProductOrder);
}
}
/**
* @ORM\Entity
* @ORM\Table(name="order_has_product")
* @Gedmo\SoftDeleteable(fieldName="deletedAt")
* @UniqueEntity(fields={"order", "product"})
*/
class OrderHasProduct {
use IdentifiedAutogeneratedEntityTrait;
/**
* Hook timestampable behavior
* updates createdAt, updatedAt fields
*/
use TimestampableEntity;
/**
* @ORM\ManyToOne(targetEntity="\Tanane\FrontendBundle\Entity\Orders", inversedBy="orderProducts")
* @ORM\JoinColumn(name="general_orders_id", referencedColumnName="id")
*/
protected $order;
/**
* @ORM\ManyToOne(targetEntity="\Tanane\ProductBundle\Entity\Product", inversedBy="orderProducts")
* @ORM\JoinColumn(name="product_id", referencedColumnName="id")
*/
protected $product;
/**
* @ORM\Column(type="integer", nullable=false)
*/
protected $amount;
/**
* @ORM\Column(name="deletedAt", type="datetime", nullable=true)
*/
protected $deletedAt;
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;
}
public function getDeletedAt()
{
return $this->deletedAt;
}
public function setDeletedAt($deletedAt)
{
$this->deletedAt = $deletedAt;
}
}
但是当我尝试在我的控制器中使用此代码编辑订单时:
public function editAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$order = $em->getRepository('FrontendBundle:Orders')->find($id);
$type = $order->getPerson()->getPersonType() === 1 ? "natural" : "legal";
$params = explode('::', $request->attributes->get('_controller'));
$actionName = substr($params[1], 0, -6);
$orderForm = $this->createForm(new OrdersType(), $order, array('action' => '#', 'method' => 'POST', 'register_type' => $type, 'curr_action' => $actionName));
return array(
"form" => $orderForm->createView(),
'id' => $id,
'entity' => $order
);
}
我收到此错误:
表单的视图数据应该是标量,数组或类型 \ ArrayAccess的实例,但是是类的实例 Proxies__CG __ \塔南\ ProductBundle \实体\产品。你可以避免这种情况 通过将“data_class”选项设置为错误 “Proxies__CG __ \ Tanane \ ProductBundle \ Entity \ Product”或添加一个 查看转换类实例的转换器 Proxies__CG __ \ Tanane \ ProductBundle \ Entity \ Product to scalar,array or \ ArrayAccess的实例。
我没有找到或知道如何解决它,能给我一些帮助吗?
答案 0 :(得分:1)
我认为这是因为这段代码
class OrdersHasProductType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('product', 'text', array(
'required' => FALSE,
'label' => FALSE
))
));
}
//...
}
意味着Symfony期望“product”成为“text”类型的字段,但是当它在OrderHasProduct上调用getProduct()
时,它会获得Product对象(或者对产品的Doctrine Proxy,因为它不是在那一点被加载)。 Symfony Fields继承自Form / AbstractType,因此它们本身就是Forms,只有一个字段,因此是错误消息。
解决方案是要创建“实体”类型的字段,要么创建一个仅提供产品名称的不同方法,例如: OrderHasProduct上的getProductName()
,然后将其用作该字段后面的数据。