Редакция формы для отношения N: M с дополнительными полями не работает

Я работаю над формой, которая обрабатывает отношения 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 __ \ Tanane \ ProductBundle \ Entity \ продукта. Вы можете избежать этого
ошибка при установке опции «data_class» в
«Proxies__CG __ \ Tanane \ ProductBundle \ Entity \ Product» или добавив
преобразователь представления, который преобразует экземпляр класса
Прокси __CG __ \ Tanane \ ProductBundle \ Entity \ Продукт в скаляр, массив или
экземпляр \ ArrayAccess.

И я не нахожу или не знаю, как это исправить, кто-нибудь может мне помочь?

0

Решение

Я думаю, что это происходит потому, что этот код

class OrdersHasProductType extends AbstractType {

public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('product', 'text', array(
'required' => FALSE,
'label' => FALSE
))
));
}
//...
}

означает, что Symfony ожидает, что «product» будет полем типа «text», но когда он вызывает getProduct() в OrderHasProduct он получает объект Product (или Doctrine Proxy для Product, поскольку в тот момент он не был загружен). Поля Symfony наследуются от Form / AbstractType, поэтому они по сути являются формами сами по себе, всего с одним полем, отсюда и сообщение об ошибке.

Решение состоит в том, чтобы либо создать это поле типа «сущность», либо создать другой метод, который дает только название продукта, например, getProductName() на OrderHasProduct, а затем использовать его в качестве данных за полем.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]