带有EntityType字段的Symfony表单生成一个';此值不应为空';如果字段在对象类中具有Valid


Symfony form with EntityType field yields a 'This value should not be blank' error if the field has a Valid() contraint in the object class

我在Symfony 2.8项目中有一个Phone类和一个Country类。Phone类的字段之一是作为Country对象的$country

我还有一个带有EntityType字段的表单,用于从数据库中的国家列表中进行选择。

我的问题是,当我从EntityType字段生成的下拉菜单中选择一个国家/地区并提交表单时,我会收到错误"This value should not be blank"在EntityField下拉菜单上方多次。

奇怪的是,我在$form->handleRequest($request);之后做了一个dump($phone),$country字段显示了从数据库中提取的正确country对象。

只有当@Assert'Valid()约束在$country字段上时才会发生这种情况。一旦我删除它,错误就会消失。问题是,我想继续验证我的Phone类的country字段。

任何关于为什么会发生这种情况的想法都将不胜感激!

Phone类:

namespace AppBundle'Entity;
use Doctrine'ORM'Mapping as ORM;
use Symfony'Component'Validator'Constraints as Assert;
/**
 * Phone
 *
 * @ORM'Table(name="phones", uniqueConstraints={@ORM'UniqueConstraint(name="natural_pk", columns={"phone_name", "country_id", "phone_number", "extension"})})
 * @ORM'Entity(repositoryClass="AppBundle'Repository'PhoneRepository")
 * @ORM'HasLifecycleCallbacks
 */
class Phone
{
    /**
     * @var int
     *
     * @ORM'Column(name="id", type="integer")
     * @ORM'Id
     * @ORM'GeneratedValue(strategy="AUTO")
     *
     * @Assert'Type(type="int")
     */
    protected $id;
    /**
     * @var Country
     *
     * @ORM'ManyToOne(targetEntity="Country")
     * @ORM'JoinColumn(nullable=false)
     *
     * @Assert'NotBlank()
     * @Assert'Valid()
     */
    protected $country;
    /**
     * @var string
     *
     * @ORM'Column(name="phone_number", type="string", length=20, nullable=false)
     *
     * @Assert'NotBlank()
     * @Assert'Type(type="string")
     * @Assert'Length(max=20)
     */
    protected $phoneNumber;
    public function __toString()
    {
        return $this->phoneNumber;
    }
    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Set phoneNumber
     *
     * @param string $phoneNumber
     *
     * @return Phone
     */
    public function setPhoneNumber($phoneNumber)
    {
        $this->phoneNumber = $phoneNumber;
        return $this;
    }
    /**
     * Get phoneNumber
     *
     * @return string
     */
    public function getPhoneNumber()
    {
        return $this->phoneNumber;
    }
    /**
     * Set country
     *
     * @param 'AppBundle'Entity'Country $country
     *
     * @return Phone
     */
    public function setCountry('AppBundle'Entity'Country $country)
    {
        $this->country = $country;
        return $this;
    }
    /**
     * Get country
     *
     * @return 'AppBundle'Entity'Country
     */
    public function getCountry()
    {
        return $this->country;
    }
}

国家类别:

namespace AppBundle'Entity;
use Doctrine'ORM'Mapping as ORM;
use Symfony'Component'Validator'Constraints as Assert;
/**
 * Country
 *
 * @ORM'Table(name="countries")
 * @ORM'Entity(repositoryClass="AppBundle'Repository'CountryRepository")
 */
class Country
{
    /**
     * @var int
     *
     * @ORM'Column(name="id", type="integer")
     * @ORM'Id
     * @ORM'GeneratedValue(strategy="AUTO")
     *
     * @Assert'Type(type="int")
     */
    protected $id;
    /**
     * @var string
     *
     * @ORM'Column(name="country_name", type="string", length=255, nullable=false)
     *
     * @Assert'NotBlank()
     * @Assert'Type(type="string")
     * @Assert'Length(max=255)
     */
    protected $countryName;
    /**
     * @var string
     *
     * @ORM'Column(name="phone_code", type="string", length=10, nullable=false)
     *
     * @Assert'NotBlank()
     * @Assert'Type(type="string")
     * @Assert'Length(max=10)
     */
    protected $phoneCode;
    public function __toString()
    {
        return $this->phoneCode;
    }
    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Set countryName
     *
     * @param string $countryName
     *
     * @return Country
     */
    public function setCountryName($countryName)
    {
        $this->countryName = $countryName;
        return $this;
    }
    /**
     * Get countryName
     *
     * @return string
     */
    public function getCountryName()
    {
        return $this->countryName;
    }
    /**
     * Set phoneCode
     *
     * @param string $phoneCode
     *
     * @return Country
     */
    public function setPhoneCode($phoneCode)
    {
        $this->phoneCode = $phoneCode;
        return $this;
    }
    /**
     * Get phoneCode
     *
     * @return string
     */
    public function getPhoneCode()
    {
        return $this->phoneCode;
    }
}

我终于找到了问题的解决方案。事实证明,我的Country类实际上有另一个来自双向关联的字段$provinces,这个字段也有Valid()约束:

/**
 * @var Province[]
 *
 * @ORM'OneToMany(targetEntity="Province", mappedBy="country")
 *
 * @Assert'Valid()
 */
protected $provinces;

我想这是导致错误的原因,因为如果$provinces是一个空数组,那么Country对象就不满足Symfony的Valid()约束。

为了解决这个问题,我必须删除Country类中$provinces字段上的Valid()约束,或者删除Phone类中的$country字段上的约束。

您可以通过在表单类型中指定不存在的验证组来禁用验证:

/**
 * {@inheritdoc}
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(['validation_groups' => ['no-validation']]); // Do not validate entities.
}

没有找到更好的解决方案:/