DiscriminatorMap持久性

时间:2013-11-08 11:16:24

标签: symfony orm doctrine-orm

对于使用鉴别器映射列持久化对象,Symfony2和Doctrine2存在一个小问题。我一直在谷歌搜索几个小时,但却找不到答案。

我正在使用的代码如下 - 我正在尝试坚持一个新用户,并基于它的“用户类型”(如表格中所声明的),新的教师/学生/随便。

如果有人善于帮助我,你能解释为什么你在做你正在做的事吗?所以我可以理解所有这些ORM的东西,这对我来说很新鲜。

这是我的SystemUser类

/**
 * SystemUser
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Bundle\MainBundle\Entity\Repository\SystemUserRepository")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="discr", type="integer")
 * @ORM\DiscriminatorMap({"0" = "SystemUser", "1" = "SchoolAdmin", "2" = "Teacher", "3" = "Student", "4" = "Guardian"})
 */
class SystemUser implements AdvancedUserInterface, \Serializable {
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=50)
     */
    protected $username;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=255)
     */
    protected $email;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=32)
     */
    protected $salt;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=64)
     */
    protected $password;

    /**
     * @var bool
     *
     * @ORM\Column(type="boolean", name="is_active")
     */
    protected $isActive;

    /**
     * @var string
     * @ORM\Column(name="birth_date", type="date")
     */
    protected $birthDate;

    /**
     * @var string
     * @ORM\Column(name="cellphone", type="string", length=10)
     */
    protected $cellphone;

    /**
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
     */
    protected $roles;

    /**
     *
     *
     *
     *
     * Begin methods
     *
     *
     *
     */


    public function __construct() {
        $this->isActive = true;
        $this->salt = md5(uniqid(null, true));
        $this->roles = new ArrayCollection();
    }

......遗漏了其他方法,因为它们似乎都很好。请注意,鉴别器没有显式列,但它仍然通过注释在架构中生成它。这是对的吗?

现在我的FormType ...

class UserFormType extends AbstractType {
    private $router;
    private $securityContext;

    public function __construct(Router $router, SecurityContextInterface $securityContext) {
        $this->router = $router;
        $this->securityContext = $securityContext;
    }
    public function buildForm(FormBuilderInterface $builder, array $options) {
        parent::buildForm($builder, $options);

        $builder->setAction($this->router->generate('register_new_user'))
            ->add('username', 'text')
            ->add('email', 'email')
            ->add('birth_date', 'date', array(
                'widget' => 'single_text',
            ))
            ->add('password', 'repeated', array(
                'first_name' => 'password',
                'second_name' => 'confirm',
                'type' => 'password',
            ))
            ->add('cellphone', 'text', array(
                'max_length' => 10,
                'invalid_message' => 'A phone number must be exactly 10 characters long',
            ));

            //Add additional stuff here like access role, status, account active, etc...
            $builder->add('roles', null, array(
                        'required' => true,
                        'multiple' => true,
                        'label' => 'Role'
                    ))
                    ->add('is_active', 'checkbox', array(
                        'required' => true,
                        'label' => 'Active'
                    ))
                                    //Here is where I get the issue mentioned below
                    ->add('discr', 'choice', array(
                        'choices' => array(
                            '1' => 'School Administrator',
                            '2' => 'Teacher',
                            '3' => 'Student',
                            '4' => 'Guardian'
    ,                   ),
                        'multiple' => false,
                        'label' => 'User Type'
                    ));

    }

    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(array(
            'data_class' => 'SCWORX\MainBundle\Entity\SystemUser',
        ));
    }

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

在我添加歧视选择字段的地方,我收到以下错误:

Neither the property "discr" nor one of the methods "getDiscr()", "isDiscr()", "hasDiscr()", "__get()" or "__call()" exist and have public access in class "Bundle\MainBundle\Entity\SystemUser". 

最后,注册表格就在这里......

class RegistrationFormType extends AbstractType {
    private $router;
    private $securityContext;

    public function __construct(Router $router, SecurityContextInterface $securityContext) {
        $this->router = $router;
        $this->securityContext = $securityContext;
    }
    public function buildForm(FormBuilderInterface $builder, array $options) {
        parent::buildForm($builder, $options);

        $builder->setAction($this->router->generate('create_user'))
                ->add('user', 'user_form')
                ->add('submit', 'submit');

    }

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

我应该注意,这两种表格都已注册为服务。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

在您的SystemUser实体类中,您没有名为“discrimin”的属性。您当前的注释是说,当我的'discr'属性包含这些不同的值(您在DiscriminatorMap中列出的值)时,实体会更改为这些不同的类型,SchoolAdmin,Teacher等。

因此,您需要将discrimin属性添加到SystemUser,然后当您在表单中使用它时,输入的值将保存在对象的该属性中,您的代码将知道该对象的SystemUser的“类型”是什么!