将所有记录插入Symfony中的连接表

将所有记录插入Symfony中的连接表,symfony,doctrine-orm,insert,many-to-many,junction-table,Symfony,Doctrine Orm,Insert,Many To Many,Junction Table,我有一个下一个表格:测验、问题和问题测验。我有一种多对多的关系。 插入工作适用于表格测验和问题,但在表格问题中,测验只插入了一条记录 我的桌子 “问题”,没关系 +----+--------+ | id | title | +----+--------+ | 61 | Title1 | | 62 | Title2 | | 63 | Title3 | +----+--------+ +----+-------+--------+ | id | name | status | +----+--

我有一个下一个表格:测验、问题和问题测验。我有一种多对多的关系。 插入工作适用于表格测验和问题,但在表格问题中,测验只插入了一条记录

我的桌子

“问题”,没关系

+----+--------+
| id | title  |
+----+--------+
| 61 | Title1 |
| 62 | Title2 |
| 63 | Title3 |
+----+--------+
+----+-------+--------+
| id | name  | status |
+----+-------+--------+
| 27 | Name1 |      0 |
+----+-------+--------+
“测验”,没关系

+----+--------+
| id | title  |
+----+--------+
| 61 | Title1 |
| 62 | Title2 |
| 63 | Title3 |
+----+--------+
+----+-------+--------+
| id | name  | status |
+----+-------+--------+
| 27 | Name1 |      0 |
+----+-------+--------+
“问答游戏”

最后一个表中必须插入61,62,63 quiestion_id,但只插入一条记录

我的控制器的碎片

   $quiz = new Quiz();
   $question = new Question();
   $form = $this->get('form.factory')->createNamed('quiz', QuizType::class, $quiz);
   $quiz->getQuestions()->add($question);
   $question->addQuiz($quiz);
   $form->handleRequest($request);
   if ($form->isSubmitted() && $form->isValid()) {
      $em = $this->getDoctrine()->getManager();
      $em->persist($quiz);
      $em->persist($question);
      $em->flush();
}
 $quiz = new Quiz();
 $question = new Question();
 //...
 $question->addQuiz($quiz);
问题实体的调用证据

  $quiz->getQuestions()->add($question);
  $question->addQuiz($quiz);
我使用集合类型,可以插入任意数量的问题

更新QuizType表单。

class QuizType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class, array('attr' => ['class' => 'form-control name-quiz'], 'label' => 'Name Quiz'))
            ->add('status', CheckboxType::class, array(
                'label'    => 'Status Quiz',
                'required' => false))
            ->add('save', SubmitType::class, ['label' => 'Add', 'attr' => ['class' => 'btn btn-primary']]);
        $builder
            ->add('questions', CollectionType::class, array(
                'entry_type' => QuestionType::class,
                'entry_options' => array('label' => false),
                'allow_add' => true,
            ));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Quiz::class
        ]);
    }
}
如果我调试方法
addQuestion()
,我会在带有参数[null]的疑问(标题)值(?)中插入错误。但如果我做了一个测试

   Question {#583 ▼
  -id: null
  -title: "123"
  -quiz: ArrayCollection {#584 ▼
    -elements: array:1 [▼
      0 => Quiz {#581 ▼
        -id: null
        -name: "123"
        -questions: ArrayCollection {#580 ▶}
        -status: false
      }
    ]
  }
  -answers: ArrayCollection {#585 ▶}
}
调试$form->get('questions')->getData()返回


没有
测验
问题
实体-很难判断。但是

我想问题出在你的控制器上

   $quiz = new Quiz();
   $question = new Question();
   $form = $this->get('form.factory')->createNamed('quiz', QuizType::class, $quiz);
   $quiz->getQuestions()->add($question);
   $question->addQuiz($quiz);
   $form->handleRequest($request);
   if ($form->isSubmitted() && $form->isValid()) {
      $em = $this->getDoctrine()->getManager();
      $em->persist($quiz);
      $em->persist($question);
      $em->flush();
}
 $quiz = new Quiz();
 $question = new Question();
 //...
 $question->addQuiz($quiz);
所以你创建了一个新的测验,应该有多个问题,对吗? 但是你只回答一次问题

$question->addQuiz($quiz);
所以正确的方法应该是(有点冗长,这样你就能明白重点)

看看这个例子(),了解许多关系,特别是
addUSerGroup()
addUser()
方法

在控制器(无表单)中尝试建议的方法,看看它是否有效,以及您是否在
question\u quick
表中获得了多行内容

更新:

我认为您正在寻找的“魔力”是测验实体中的
cascade={“persist”}
。看看这篇文章()。尽管视频不是免费的,但是文本是可以的

1) 在您的实体中设置
cascade

2) 更新了测验类中的you
addQuestion()
方法,如下所示

public function addQuestion(Question $question)
{
  // do not add same questions more than once. 
  if ($this->questions->contains($question)) {
    return;
  }
  $this->questions[] = $question; // to add new question to that quiz
  $question->addQuiz($this); // this quiz now also belongs to a question
}
3) 获取嵌入集合以使用
prototype
=>。因此,您可以随时添加新问题

4) 提交后,只需拨打:

if ($form->isSubmitted() && $form->isValid()) {
   $quiz = $form->getData();
   $em->persist($quiz);
   $em->flush();
}
4.1)如果不起作用,请尝试在提交的问题集合上循环

if ($form->isSubmitted() && $form->isValid()) {
   $quiz = $form->getData();
   // since getQuestions() gives you an ArrayCollection, isEmpty is a built in method
   if(!$quiz->getQuestions()->isEmpty())
   {
     // this is kinda bad, but you'll have to debug and play around
     foreach ($quiz->getQuestions() as $new_question)
     {
       $em->persist($new_question);
     }
   }
   $em->persist($quiz);
   $em->flush();
}

我解决了我的问题。我发布我的代码,也许它会帮助别人

我的实体
问题

class Question
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

/**
 * @ORM\Column(type="text")
 */
private $title;

/**
 * @ORM\ManyToMany(targetEntity="App\Entity\Quiz", inversedBy="questions")
 */
private $quiz;


public function __construct()
{
    $this->quiz = new ArrayCollection();
}

public function getId(): ?int
{
    return $this->id;
}

public function getTitle(): ?string
{
    return $this->title;
}

public function setTitle(string $title): self
{
    $this->title = $title;

    return $this;
}


/**
 * @return Collection|Quiz[]
 */
public function getQuiz(): Collection
{
    return $this->quiz;
}

public function addQuiz(Quiz $quiz): self
{
    if (!$this->quiz->contains($quiz)) {
        $this->quiz[] = $quiz;
    }

    return $this;
}

public function removeQuiz(Quiz $quiz): self
{
    if ($this->quiz->contains($quiz)) {
        $this->quiz->removeElement($quiz);
    }

    return $this;
    }
}
我的实体
测验

class Quiz
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;
/**
 * @ORM\Column(type="string", length=191)
 */
private $name;
/**
 * @ORM\ManyToMany(targetEntity="App\Entity\Question", mappedBy="quiz", cascade={"persist"})
 */
private $questions;

/**
 * @ORM\Column(type="boolean")
 */
private $status;

public function __construct()
{
    $this->questions = new ArrayCollection();
}

public function getId(): ?int
{
    return $this->id;
}

/**
 * @return string|null
 */
public function getName(): ?string
{
    return $this->name;
}

public function setName(string $name): self
{
    $this->name = $name;

    return $this;
}

/**
 * @return Collection|Question[]
 */
public function getQuestions(): Collection
{
    return $this->questions;
}

public function addQuestion(Question $question): self
{
    if (!$this->questions->contains($question)) {
        $this->questions[] = $question;
        $question->addQuiz($this);
    }

    return $this;
}

public function removeQuestion(Question $question): self
{
    if ($this->questions->contains($question)) {
        $this->questions->removeElement($question);
        $question->removeQuiz($this);
    }

    return $this;
}

public function getStatus(): ?bool
{
    return $this->status;
}

public function setStatus(bool $status): self
{
    $this->status = $status;

    return $this;
   }
}
问题类型
表格

 public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', TextareaType::class, array('attr' => array('class' => 'form-control'), 'label' => false));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Question::class
        ]);
    }
   public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class, array('attr' => ['class' => 'form-control name-quiz'], 'label' => 'Name quiz'))
            ->add('status', CheckboxType::class, array(
                'label'    => 'Status quiz',
                'required' => false))
            ->add('save', SubmitType::class, ['label' => 'Add', 'attr' => ['class' => 'btn btn-primary']]);
        $builder
            ->add('questions', CollectionType::class, array(
                'entry_type' => QuestionType::class,
                'entry_options' => array('label' => false),
                'allow_add' => true,
                'by_reference' => false,
            ));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Quiz::class
        ]);
    }
QuizType
表单

 public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', TextareaType::class, array('attr' => array('class' => 'form-control'), 'label' => false));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Question::class
        ]);
    }
   public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class, array('attr' => ['class' => 'form-control name-quiz'], 'label' => 'Name quiz'))
            ->add('status', CheckboxType::class, array(
                'label'    => 'Status quiz',
                'required' => false))
            ->add('save', SubmitType::class, ['label' => 'Add', 'attr' => ['class' => 'btn btn-primary']]);
        $builder
            ->add('questions', CollectionType::class, array(
                'entry_type' => QuestionType::class,
                'entry_options' => array('label' => false),
                'allow_add' => true,
                'by_reference' => false,
            ));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Quiz::class
        ]);
    }
最后是我的控制器

    $quiz = new Quiz();
    $form = $this->get('form.factory')->createNamed('quiz', QuizType::class, $quiz);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($quiz);
        $em->flush();
        return $this->redirectToRoute('admin');

    }

很好,是的:)谢谢大家。

请出示您的
测验类型?似乎从提交的数据到您的
测验
实体的映射没有像您预期的那样工作。@xabbuhI我已更新。哦,您是否也可以显示您的
测验
问题
实体?@xabbuh请看这里。我想知道
$this->questions[]=$question,如果真的有效
$this->questions
在您的
测验中
实体是一个条令集合。所以我希望这一行是
$this->questions->add($question)。这对我不起作用,因为我想插入任意数量的问题。在你的例子中,我只能添加3个问题。我已经看到链接了。我尝试了联接表和联接列,但对我无效。这是不正确的。通过这种方法,您可以在测验中添加任意数量的问题。为了演示,我创建了三个问题,并将每个问题添加到一个测验中。如果您将
cascade={“persist”}
添加到测验的许多注释中,您将获得自动持久化,因此您不需要手动调用
$em->persist($quesion\u X)