7

I have a Quiz structure with 3 entities:

  • Quiz has Questions (OneToMany)
  • Question has Quiz (ManyToOne)
  • Question has Answers (OneToMany)
  • Answer has Question (ManyToOne)

The code looks like such:

Quiz Entity

class Quiz { /** * @ORM\OneToMany(targetEntity="Question", mappedBy="quiz", cascade={"persist", "remove"}) */ private $questions; public function __construct() { $this->questions = new ArrayCollection(); } public function addQuestion(\Cariboo\QuizBundle\Entity\Question $questions) { $questions->setQuiz( $this ); // die(); Not dying here... $this->questions[] = $questions; return $this; } public function removeQuestion(\Cariboo\QuizBundle\Entity\Question $questions) { $this->questions->removeElement($questions); } public function getQuestions() { return $this->questions; } } 

Question Entity

class Question { /** * @ORM\OneToMany(targetEntity="Answer", mappedBy="question", cascade={"persist", "remove"}) */ private $answers; /** * @ORM\ManyToOne(targetEntity="Cariboo\QuizBundle\Entity\Quiz", cascade={"persist"}) */ private $quiz; public function addAnswer(\Cariboo\QuizBundle\Entity\Answer $answers) { $answers->setQuestion( $this ); $this->answers[] = $answers; return $this; } public function removeAnswer(\Cariboo\QuizBundle\Entity\Answer $answers) { $this->answers->removeElement($answers); } public function getAnswers() { return $this->answers; } public function setQuiz(\Cariboo\QuizBundle\Entity\Quiz $quiz = null) { $this->quiz = $quiz; return $this; } public function getQuiz() { return $this->quiz; } } 

Answer entity

class Answer { /** * @ORM\ManyToOne(targetEntity="Cariboo\QuizBundle\Entity\Question") */ private $question; public function setQuestion(\Cariboo\QuizBundle\Entity\Question $question = null) { $this->question = $question; return $this; } public function getQuestion() { return $this->question; } } 

I cascade persist them.

I configured my setters as explained in Cascaded persist not working (Doctrine ORM + Symfony 2)

The addAnswer gets executed and for answers, the Question is set properly. However the addQuestion does not set the quiz.

image of what gets dumped upon sending the form

I can add a foreach in my controller but I am not satisfied with this, as I feel I am not exploiting symfony's power. ( No duplicate of Entity doesn't associate correctly )

 if ( $form->isValid() ) { foreach ( $quiz->getQuestions() as $question ) { $question->setQuiz( $quiz ); } $em = $this->getDoctrine()->getManager(); $em->persist( $quiz ); $em->flush(); return $this->redirect( $this->generateUrl( 'quiz_show', array( 'slug' => $quiz->getSlug() ) ) ); } 

I cannot figure out why the addQuestion does not get executed.

Edit

My Quiz form

 $builder ->add( 'questions', 'collection', array( 'type' => new QuestionType(), 'allow_add' => true, 'allow_delete' => true, 'prototype' => true, 'prototype_name' => '__qst_prot__' ) ) ; 

Partial builder of Question

 $builder ->add( 'question', 'text' ) ->add( 'answers', 'collection', array( 'type' => new AnswerType(), 'allow_add' => true, 'allow_delete' => true, 'prototype' => true, 'prototype_name' => '__asw_prot__' ) ); 

My Answer form

$builder ->add( 'answer', 'text' ) ->add( 'correct' ) ; 
3
  • 1
    Possible duplicate of Entity doesn't associate correctly Commented Feb 25, 2016 at 10:48
  • 2
    i think that collection type creates problem here. How about setting by_reference to false (in Quiz form)? Commented Feb 25, 2016 at 12:24
  • 1
    Setting by_reference works wonders! I have no idea why it worked for Answers without it though. Commented Feb 25, 2016 at 13:19

1 Answer 1

4

Problem is in collection form type. You need to set by_reference to false if you want to call parent entity setter.

Symfony docs:

Similarly, if you're using the CollectionType field where your underlying collection data is an object (like with Doctrine's ArrayCollection), then by_reference must be set to false if you need the adder and remover (e.g. addAuthor() and removeAuthor()) to be called.

Read more here: http://symfony.com/doc/current/reference/forms/types/collection.html#by-reference

Sign up to request clarification or add additional context in comments.

2 Comments

Yet I can die in addAnswer but not in addQuestion. The similar appearance of Answer and Question also startles me.
I added the form builder in an edit ;) I did not add the js that generates the fields from the prototypes.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.