我在任何地方都搜索可以帮助我解决这个问题并且找不到。
我有关系:
表A ---一对多---表AB ---多对一---表B
错误尝试调用newAction方法时得到的结果:
Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "AppBundle\Entity\Line#$buttons", got "AppBundle\Entity\Button" instead.
我认为我已经尝试了所有内容并且仍然遇到同样的错误。
行实体
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Line
*
* @ORM\Table(name="lines")
* @ORM\Entity(repositoryClass="AppBundle\Repository\LineRepository")
*/
class Line
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="line_name", type="string", length=255)
*/
private $lineName;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\ButtonsState", mappedBy="line", cascade={"all"})
*/
private $buttons;
public function __construct()
{
$this->buttons = new ArrayCollection();
}
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set lineName
*
* @param string $lineName
*
* @return Line
*/
public function setLineName($lineName)
{
$this->lineName = $lineName;
return $this;
}
/**
* Get lineName
*
* @return string
*/
public function getLineName()
{
return $this->lineName;
}
/**
* Get buttons
*
* @return int
*/
public function getButtons()
{
return $this->buttons;
}
public function addButton(Button $button)
{
if ($this->buttons->contains($button)) {
return;
}
$this->buttons->add($button);
}
}
按钮实体
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Button
*
* @ORM\Table(name="buttons")
* @ORM\Entity(repositoryClass="AppBundle\Repository\ButtonRepository")
*/
class Button
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="button_name", type="string", length=255)
*/
private $buttonName;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\ButtonsState", mappedBy="button", cascade={"all"})
*/
private $lines;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Get buttonName
*
* @return string
*/
public function getButtonName()
{
return $this->buttonName;
}
/**
* Set buttonName
*
* @param string $buttonName
*
* @return Button
*/
public function setButtonName($buttonName)
{
$this->buttonName = $buttonName;
}
}
ButtonsState实体
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* ButtonsState
*
* @ORM\Table(name="lines_buttons")
* @ORM\Entity(repositoryClass="AppBundle\Repository\ButtonStateRepository")
*/
class ButtonsState
{
/**
* @ORM\Id()
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Line", inversedBy="buttons", cascade={"PERSIST"})
* @ORM\JoinColumn(name="line_id", referencedColumnName="id")
*/
private $line;
/**
* @ORM\Id()
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Button", inversedBy="line", cascade={"PERSIST"})
* @ORM\JoinColumn(name="button_id", referencedColumnName="id")
*/
private $button;
/**
* @var int
*
* @ORM\Column(name="state", type="integer")
*/
private $state;
/**
* @return int
*/
public function getState()
{
return $this->state;
}
/**
* @param int $state
*/
public function setState($state)
{
$this->state = $state;
}
}
LineController
/**
* Creates a new line entity.
*
* @Route("/new", name="line_new")
* @Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$line = new Line();
$form = $this->createForm('AppBundle\Form\LineType', $line);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
foreach ($line->getButtons() as $button) {
$line->addButton($button);
}
$em->persist($line);
$em->flush();
return $this->redirectToRoute('line_index', array('id' => $line->getId()));
}
return $this->render('line/new.html.twig', array(
'line' => $line,
'form' => $form->createView(),
));
}
线型
namespace AppBundle\Form;
use AppBundle\Entity\Button;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class LineType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('lineName', null, array(
'label' => 'Line name',
))
->add('buttons', EntityType::class, array(
'class' => Button::class,
'choice_label' => 'buttonName',
'multiple' => true,
'expanded' => true,
));
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Line'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_line';
}
}
答案 0 :(得分:0)
在控制器的第51行,您正在调用方法addButtons
。
foreach ($line->getButtons() as $button) {
$line->addButtons($button);
}
尝试将其更改为addButton
,因为这是实体中定义的方法。
如果这没有帮助,请提供相应的堆栈跟踪。
修改强>
再看一遍,我已经看到了问题所在。
你将ButtonsState Entity视为m到m之间关系的表,因为它上面有一个额外的属性。
在表单类型中,你说在Line实体的按钮属性后面有按钮。这是错的。在这个属性后面有ButtonsState实体。
所以改变你的代码如下:
表格类型:
// ...
->add('buttonsToAdd', EntityType::class, array(
'class' => Button::class,
'choice_label' => 'buttonName',
'multiple' => true,
'expanded' => true,
'mapped' => false,
))
// ...
控制器:
// ...
$em->persist($line);
foreach ($form->get('buttonsToAdd')->getData() as $button) {
$state = new \UserBundle\Entity\ButtonsState();
$state->setLine($line);
$state->setButton($button);
$state->setState(0);
$line->addButton($state);
}
$em->flush();
// ...
像这样你有一个额外的(未映射的)属性,可以使用窗体上的按钮转换为控制器中的ButtonsState实例。
还有一个提示:使用命令bin/console doctrine:generate:entities AppBundle:ButtonsState
在您的实体中生成getter和setter,因为它们在某些地方是wronc / incomplete。
答案 1 :(得分:0)
<强>从强>
class ButtonsState
{
/**
* @ORM\Id()
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Button", inversedBy="line", cascade={"PERSIST"})
* @ORM\JoinColumn(name="button_id", referencedColumnName="id")
*/
private $button;
}
到
class ButtonsState
{
/**
* @ORM\Id()
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Button", inversedBy="lines", cascade={"PERSIST"}) // added a 's' behind line
* @ORM\JoinColumn(name="button_id", referencedColumnName="id")
*/
private $button;
}
下次检查你的关系:
bin / console doctrine:schema:validate