2013-11-08 2 views
1

Имея небольшую небольшую проблему с Symfony2 и Doctrine2 в отношении сохранения объекта с помощью столбца карты дискриминатора. Я уже много часов гуляю, но не могу найти ответ.DiscriminatorMap Persistence

Код, который я использую ниже, - я пытаюсь сохранить нового пользователя и на основе его «пользовательского типа» (как заявлено в форме), нового Учителя/Студента/Независимо.

Если кто-то добр, чтобы помочь мне, не могли бы вы также объяснить, почему вы делаете то, что делаете? Только поэтому я могу понять смысл всего этого материала 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'; 
    } 
} 

Где добавить поле выбора DISCR, я получаю следующее сообщение об ошибке:

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'; 
    } 
} 

Возможно, следует отметить, что обе формы зарегистрированы как службы.

Спасибо за помощь!

ответ

0

В классе сущности SystemUser у вас нет свойства, называемого «discr». В вашей текущей аннотации говорится, что когда мое свойство «discr» содержит эти разные значения (те, которые вы указали в DiscriminatorMap), сущность изменяется на эти разные типы, SchoolAdmin, Teacher и т. Д.

Итак, вам нужно добавить свойство discr для SystemUser, тогда, когда вы используете его в своей форме, введенное значение будет сохранено в этом свойстве на объекте, и ваш код будет знать, что такое «тип» SystemUser этого объекта!

+0

Спасибо за ответ! Я добавил 'protected $ discr' в класс SystemUser вместе с его getters (' getDiscr() ') и setter (' setDiscr() '), запустил doctrine: generate: entity Bundle. Теперь я больше не получаю эту ошибку, но она не сохраняет выбранное значение для БД. Есть идеи? РЕДАКТИРОВАТЬ - я не комментировал новый $ discrityy, поскольку доктрина жаловалась, что это дубликат - это правильно? – iLikeBreakfast

+0

Вы сами добавили геттеры/сеттеры, или вы позволили команде generate: entities добавить их для вас? – Tocacar

+0

Добавил их сам. – iLikeBreakfast