2017-10-18 127 views
0

我目前正在開發一個Symfony v3.3.6項目。 我有一個用於創建用戶的表單。 我想確保電子郵件和用戶名(fos用戶包)是唯一的。Symfony - 唯一的實體約束不起作用

我目前擁有這個模型(僅一小部分):

<?php 

namespace ProjectBundle\Entity\User; 

use Doctrine\ORM\Mapping as ORM; 
use FOS\UserBundle\Model\User as BaseUser; 
use Gedmo\Mapping\Annotation as Gedmo; 
use Gedmo\SoftDeleteable\Traits\SoftDeleteableEntity; 
use Gedmo\Timestampable\Traits\TimestampableEntity; 
use ProjectBundle\Entity\Gender\Gender; 
use ProjectBundle\Entity\Organisation\Organisation; 
use ProjectBundle\Entity\Traits\BlameableEntity; 
use ProjectBundle\Entity\User\Profile; 
use Symfony\Component\Security\Core\User\AdvancedUserInterface; 
use Symfony\Component\Validator\Constraints as Assert; 
use Symfony\Component\Validator\Context\ExecutionContextInterface; 
use Doctrine\Common\Collections\ArrayCollection; 
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; 
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator; 


/** 
* @ORM\Entity(repositoryClass="ProjectBundle\Repository\User\UserRepository") 
* @Gedmo\SoftDeleteable(fieldName="deletedAt") 
* @ORM\Entity 
* @UniqueEntity(fields={"email"}, groups={"registration"}) 
* @UniqueEntity(fields={"username"}, groups={"registration"}) 
* @ORM\Table(name="user") 
*/ 
class User extends BaseUser implements AdvancedUserInterface, \Serializable 
{ 
    use TimestampableEntity; 
    use SoftDeleteableEntity; 
    use BlameableEntity; 

    const ID_ORGA_GC = 1; 

    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 


    /** 
    * @Assert\NotBlank() 
    */ 
    protected $username; 

    /** 
    * @Assert\NotBlank(groups={"registration"}) 
    * @Assert\Length(groups={"registration"}, 
    *  min = 2, 
    *  max = 254, 
    *  minMessage = "Votre mot de passe doit comporter au minimum {{ limit }} caractères.", 
    *  maxMessage = "Votre mot de passe doit comporter au maximum {{ limit }} caractères." 
    *) 
    * 
    * @var string 
    */ 
    protected $plainPassword; 


    /** 
    * @Assert\NotBlank() 
    * @Assert\Email(
    *  message = "L'adresse mail '{{ value }}' n'est pas valide.", 
    *  checkMX = true 
    *) 
    * 
    * @var string 
    */ 
    protected $email; 

正如你可以看到我加2「唯一的實體」屬性,輸入用戶名和電子郵件,還與每一個「NotBlank」約束。

在我的控制,我打電話給我的表格:

$form = $this->createForm('ProjectBundle\Form\User\UserType', $entity,array('organisation' => $organisations, 'validation_groups' => array('Default','registration'))); 

$form->handleRequest($request); 

     if ($form->isSubmitted()) { 
      if ($form->isValid()) { 

然而,即使我寫的已經存在的E-mail地址,我進入狀態,並在時機成熟時進行沖洗我得到一個大的SQL錯誤:

SQLSTATE [23000]: Integrity constraint violation: 1062 Duplicate entry '[email protected]' for key 'UNIQ_8D93D649A0D96FBF' 

但有趣的一句話是,「NotBlank」約束正常工作,並顯示出我的我的看法「的值不能爲空」

這裏我的表單:

class UserType extends AbstractType 
{ 
    /** 
    * {@inheritdoc} 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('lastname',null,array('required' => true)) 
      ->add('firstname') 
      ->add('gender',null,array('required'=>true)) 
      ->add('organisationMember',null,array(
       'required' => true, 
       'choices' => $options['organisation'], 
       'group_by' => 'type_organisation', 
       'placeholder' => 'Choisissez votre organisation' 
      )) 
      ->add('job') 
      ->add('lang', null, array(
       'required' => true 
      )) 
      ->add('mobile',null, array(
       'required' => false 
      )) 
      ->add('phone', null, array(
       'required' => true 
      )) 
      ->add('enabled') 
      ->add('is_external') 
      ->add('alert_failure') 
      ->add('alert_full') 
      ->add('alert_other') 
      ->add('plainPassword', TextType::class, array('required' => false)) 
      ->add('email') 
      ->add('profile', null, array(
       'required' => true, 
       'placeholder' => 'Choose an organisation !', 
      )); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'ProjectBundle\Entity\User\User', 
      'organisation' => 'ProjectBundle\Entity\Organisation\Organisation', 
      'profiles' => 'ProjectBundle\Entity\User\Profile', 
      'csrf' => true, 
     )); 

    } 
} 

如果有人有解決方案。

預先感謝您!

+0

[Doctrine 2 @Gedmo \ SoftDeleteable和唯一字段]的可能重複(https://stackoverflow.com/questions/33533761/doctrine-2-gedmo-softdeleteable-and-unique-fields) –

+0

錯誤幾乎完全相同但提出的解決方案不起作用,我仍然有SQL異常。 –

回答

0

你有沒有嘗試過這樣的:

/** 
* @ORM\Entity(repositoryClass="ProjectBundle\Repository\User\UserRepository") 
* @Gedmo\SoftDeleteable(fieldName="deletedAt") 
* @ORM\Entity 
* @UniqueEntity(fields={"email", "username"}, groups={"registration"}) 
* @ORM\Table(name="user") 
*/ 

但要確保你有一個電子郵件地址和用戶名的唯一索引。

+0

您的解決方案僅適用於DEV。當我更新PROD的更改時,異常仍然存在。 (數據庫已經準備好了索引) –

0

目前,@ CarcaBot的響應僅適用於DEV,在文件完全相同的情況下,更新不會在PROD中更改我的問題以及數據庫。

一個想法?