【问题标题】:Combine Questionnaire with User entity in form - symfony2将问卷与表单中的用户实体结合起来 - symfony2
【发布时间】:2013-06-05 21:51:36
【问题描述】:

我需要在我的注册表单中添加多项选择题问卷。问题和选项分为两个实体:

<?php

namespace Me\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Question
 *
 * @ORM\Table(name="question")
 * @ORM\Entity(repositoryClass="Me\UserBundle\Entity\QuestionRepository")
 */
class Question
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="questionText", type="text")
 */
private $questionText;

/**
 * @var boolean $expanded
 *
 * @ORM\Column(name="expanded", type="boolean")
 */
private $expanded;

/**
 * @var boolean $multiple
 *
 * @ORM\Column(name="multiple", type="boolean")
 */
private $multiple;

/**
 * @var Questionnaire $questionnaire
 *
 * @ORM\ManyToOne(targetEntity="Questionnaire", inversedBy="questions")
 * @ORM\JoinColumn(name="questionnaire", referencedColumnName="id", onDelete="cascade")
 */
private $questionnaire;

/**
 * @var \Doctrine\Common\Collections\ArrayCollection $options
 *
 * @ORM\OneToMany(targetEntity="Option", mappedBy="question", cascade={"all"})
 */
private $options;

public function __construct()
{
    $this->expanded = false;
    $this->multiple = false;

    $this->options = new ArrayCollection();
}


/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set questionText
 *
 * @param string $questionText
 * @return Question
 */
public function setQuestionText($questionText)
{
    $this->questionText = $questionText;

    return $this;
}

/**
 * Get questionText
 *
 * @return string 
 */
public function getQuestionText()
{
    return $this->questionText;
}

/**
 * @param mixed $options
 */
public function setOptions($options)
{
    $this->options[] = $options;

    return $this;

}

/**
 * @return mixed
 */
public function getOptions()
{
    return $this->options;
}

function __toString()
{
    return $this->getQuestionText();
}

/**
 * @param boolean $expanded
 */
public function setExpanded($expanded)
{
    $this->expanded = $expanded;
}

/**
 * @return boolean
 */
public function getExpanded()
{
    return $this->expanded;
}

/**
 * @param boolean $multiple
 */
public function setMultiple($multiple)
{
    $this->multiple = $multiple;
}

/**
 * @return boolean
 */
public function getMultiple()
{
    return $this->multiple;
}

/**
 * @param \Me\UserBundle\Entity\Questionnaire $questionnaire
 */
public function setQuestionnaire($questionnaire)
{
    $this->questionnaire = $questionnaire;
}

/**
 * @return \Me\UserBundle\Entity\Questionnaire
 */
public function getQuestionnaire()
{
    return $this->questionnaire;
}


}

<?php

namespace Me\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * QuestionOption
 *
 * @ORM\Table(name="option")
 * @ORM\Entity(repositoryClass="Me\UserBundle\Entity\OptionRepository")
 */
class Option
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var integer
 *
 * @ORM\Column(name="questionId", type="integer")
 */
private $questionId;

/**
 * @var string
 *
 * @ORM\Column(name="optionText", type="string", length=255)
 */
private $optionText;

/**
 * @ORM\ManyToOne(targetEntity="Question", inversedBy="options")
 * @ORM\JoinColumn(name="questionId", referencedColumnName="id", onDelete="cascade")
 **/
private $question;

/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set optionText
 *
 * @param string $optionText
 * @return Option
 */
public function setOptionText($optionText)
{
    $this->optionText = $optionText;

    return $this;
}

/**
 * Get optionText
 *
 * @return string 
 */
public function getOptionText()
{
    return $this->optionText;
}

/**
 * @return mixed
 */
public function getQuestion()
{
    return $this->question;
}

/**
 * @param mixed $question
 */
public function setQuestion($question)
{
    $this->question = $question;
}

/**
 * @param int $id
 */
public function setId($id)
{
    $this->id = $id;
}

function __toString()
{
    return $this->getOptionText();
}
}

我也有一个问卷实体,但我认为我并不真正需要它,因为用户不会创建问卷,只会在注册期间填写单个问卷。

我的用户实体:

<?php

namespace Me\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * User
 *
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="Me\UserBundle\Entity\UserRepository")
 */
class User
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="firstName", type="string", length=50)
 */
private $firstName;

/**
 * @var string
 *
 * @ORM\Column(name="middleInitial", type="string", length=50)
 */
private $middleInitial;

/**
 * @var string
 *
 * @ORM\Column(name="lastName", type="string", length=50)
 */
private $lastName;

/**
 * @var string
 *
 * @ORM\Column(name="homePhoneArea", type="string", length=3)
 */
private $homePhoneArea;

/**
 * @var string
 *
 * @ORM\Column(name="homePhoneNumber", type="string", length=7)
 */
private $homePhoneNumber;

/**
 * @var string
 *
 * @ORM\Column(name="email", type="string", length=50)
 */
private $email;

/**
 * @var \Doctrine\Common\Collections\ArrayCollection
 */
public $questions;

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

/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set firstName
 *
 * @param string $firstName
 * @return User
 */
public function setFirstName($firstName)
{
    $this->firstName = $firstName;

    return $this;
}

/**
 * Get firstName
 *
 * @return string 
 */
public function getFirstName()
{
    return $this->firstName;
}

/**
 * Set middleInitial
 *
 * @param string $middleInitial
 * @return User
 */
public function setMiddleInitial($middleInitial)
{
    $this->middleInitial = $middleInitial;

    return $this;
}

/**
 * Get middleInitial
 *
 * @return string 
 */
public function getMiddleInitial()
{
    return $this->middleInitial;
}

/**
 * Set lastName
 *
 * @param string $lastName
 * @return User
 */
public function setLastName($lastName)
{
    $this->lastName = $lastName;

    return $this;
}

/**
 * Get lastName
 *
 * @return string 
 */
public function getLastName()
{
    return $this->lastName;
}

/**
 * Set homePhoneArea
 *
 * @param string $homePhoneArea
 * @return User
 */
public function setHomePhoneArea($homePhoneArea)
{
    $this->homePhoneArea = $homePhoneArea;

    return $this;
}

/**
 * Get homePhoneArea
 *
 * @return string 
 */
public function getHomePhoneArea()
{
    return $this->homePhoneArea;
}

/**
 * Set homePhoneNumber
 *
 * @param string $homePhoneNumber
 * @return User
 */
public function setHomePhoneNumber($homePhoneNumber)
{
    $this->homePhoneNumber = $homePhoneNumber;

    return $this;
}

/**
 * Get homePhoneNumber
 *
 * @return string 
 */
public function getHomePhoneNumber()
{
    return $this->homePhoneNumber;
}


/**
 * Set email
 *
 * @param string $email
 * @return User
 */
public function setEmail($email)
{
    $this->email = $email;

    return $this;
}

/**
 * Get email
 *
 * @return string 
 */
public function getEmail()
{
    return $this->email;
}



/**
 * @return \Doctrine\Common\Collections\ArrayCollection
 */
public function getQuestions()
{
    return $this->questions;
}


}

我的用户控制器:

public function newAction()
{
    $user = new User();

    $em = $this->getDoctrine()->getManager();

    $questions = $em->getRepository('MeUserBundle:Question')->findAll();



    if (!$questions) {
        throw $this->createNotFoundException('Unable to find Questions.');
    }

    $builder = $this->createFormBuilder();

    $optionEntities = array();
    foreach ($questions as $question)
    {
        $options = array();
        foreach ($question->getOptions() as $option)
        {
            $options[$option->getId()] = $option->getOptionText();
            $optionEntities[$option->getId()] = $option;
        }
        $builder->add('question_'. $question->getId(), 'choice', array(
            'label' => $question->getQuestionText(),
            'expanded' => $question->getExpanded(),
            'multiple' => $question->getMultiple(),
            'choices' => $options
        ));
    }

    $user->getQuestions()->add($questions);

    $form = $this->createForm(new MyFormType(), array('User' => $user));

    return $this->render('MeUserBundle:User:new.html.twig', array(
        'entity' => $user,
        'form'   => $form->createView(),
    ));
}

目前的表单类型:

<?php

namespace Me\UserBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class MyFormType extends AbstractType
{
protected $questions;

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

public function buildForm(FormBuilderInterface $builder, array $options)
{

    $builder
        ->add('questions', 'collection', array(
            'type' => new QuestionType()
        ))
        ->add('firstName')
        ->add('middleInitial')
        ->add('lastName')
        ->add('homePhoneArea')
        ->add('homePhoneNumber')
        ->add('email')
    ;
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(

    ));
}

public function getName()
{
    return 'myform_type';
}
}

此设置无法获取问题及其相关选项,并无法在同一用户创建表单中显示它们。我已经看到了组合表单的说明和文档,但没有使用这种配置创建表单。任何指导将不胜感激。

【问题讨论】:

  • 只是为了澄清一下,用户和问题是否有任何关系?并且,您可以发布您的 MyFormType 表单吗?
  • 您想在哪里存储答案?
  • 向我们展示您的用户实体和您的 MyFormType 表单
  • 我一直专注于尝试显示此表单,我还没有考虑过处理/存储响应。
  • 按要求添加实体和表单类型

标签: php symfony doctrine-orm symfony-forms symfony-2.3


【解决方案1】:

我不确定我是否正确理解了您的问题,但也许这会有所帮助。

据我所知,您正在构建表单(用于问题),但您没有在任何地方使用它!最简单的方法是将问题(在您的情况下为 $user->getQuestions() )传递给 MyFormType 并在类型中添加所有问题。

所以它看起来像这样

$this->createForm(new MyFormType($user->getQuestions()), array('User' => $user));

在你的类型中

protected $questions;

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

protected $questions;

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

public function buildForm(FormBuilderInterface $builder, array $options) 
{
    foreach ($this->questions as $question) 
    {
        $options = array();
        foreach ($question->getOptions() as $option)
        {
            $options[$option->getId()] = $option->getOptionText();
            $optionEntities[$option->getId()] = $option;
        }
        $builder->add('question_'. $question->getId(), 'choice', array(
            'label' => $question->getQuestionText(),
            'expanded' => $question->getExpanded(),
            'multiple' => $question->getMultiple(),
            'choices' => $options
        ));
    }
 }

编辑 1

您为什么不尝试以下方法?

在 User 中添加方法 setQuestionnaire 并创建一个名为 QuestionnaireType 的类型,负责创建整个问卷 在 UserType(对不起,名称错误)中,将 QuestionnaireType 添加为嵌入式表单 一旦用户提交数据并且您调用绑定 symfony 将把整个问卷对象传递给 created 方法,以便您可以对其进行迭代并保存用户的回答!

【讨论】:

  • 如何处理这个错误?类“Me\UserBundle\Entity\User”中既不存在属性“question_13”,也不存在方法“getQuestion13()”或方法“isQuestion13()” 它试图遍历问题并且无法在用户实体中找到它们,这是正确的,因为它们在 Question 实体中
  • 对不起,我误解了这个问题。阅读我的答案,看看是否有帮助:)
  • 我已经为此发布了一个赏金,如果你发布我可以学习的工作代码,我很高兴将它奖励给你。
【解决方案2】:

您的用户实体需要与他的 $answers 的关系,您应该将其存储在用户实体的 $answers-field 中,(查找“嵌入集合”)

然后在您的控制器中消化表单,您通过 $user->setAnswers(value)) 存储值,然后您将在用户实体的 $answers 字段 ($user->getAnswers()) 中找到答案值.

并且不要忘记添加您的 getter 和 setter。

$php app/console 原则:generate:entities BundleName:Entityname

【讨论】:

    【解决方案3】:

    首先你可以在用户中添加一个setQuestions方法,这个方法会收到一个ArrayCollection。

    那你看http://symfony.com/doc/current/reference/forms/types/collection.html了吗?

    也许你可以问自己这个表格应该显示/做什么 是否需要嵌入一个集合或 QuestionFormType 列表可以吗?

    每次我必须做嵌入式表单类型时,我都会画草图和活动图,以确保不会陷入复杂的表单结构

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      • 2015-02-10
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多