我在Symfony 2.8项目中有一个Phone
类和一个Country
类。Phone
类的字段之一是作为Country
对象的$country
。
我还有一个带有EntityType字段的表单,用于从数据库中的国家列表中进行选择。
我的问题是,当我从EntityType字段生成的下拉菜单中选择一个国家/地区并提交表单时,我会收到错误"This value should not be blank"在EntityField下拉菜单上方多次。
奇怪的是,我在$form->handleRequest($request);
之后做了一个dump($phone)
,$country字段显示了从数据库中提取的正确country对象。
只有当@AssertValid()
约束在$country
字段上时才会发生这种情况。一旦我删除它,错误就会消失。问题是,我想继续验证我的Phone
类的country字段。
任何关于为什么会发生这种情况的想法都将不胜感激!
Phone
类:
namespace AppBundleEntity;
use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;
/**
* Phone
*
* @ORMTable(name="phones", uniqueConstraints={@ORMUniqueConstraint(name="natural_pk", columns={"phone_name", "country_id", "phone_number", "extension"})})
* @ORMEntity(repositoryClass="AppBundleRepositoryPhoneRepository")
* @ORMHasLifecycleCallbacks
*/
class Phone
{
/**
* @var int
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*
* @AssertType(type="int")
*/
protected $id;
/**
* @var Country
*
* @ORMManyToOne(targetEntity="Country")
* @ORMJoinColumn(nullable=false)
*
* @AssertNotBlank()
* @AssertValid()
*/
protected $country;
/**
* @var string
*
* @ORMColumn(name="phone_number", type="string", length=20, nullable=false)
*
* @AssertNotBlank()
* @AssertType(type="string")
* @AssertLength(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 AppBundleEntityCountry $country
*
* @return Phone
*/
public function setCountry(AppBundleEntityCountry $country)
{
$this->country = $country;
return $this;
}
/**
* Get country
*
* @return AppBundleEntityCountry
*/
public function getCountry()
{
return $this->country;
}
}
国家类别:
namespace AppBundleEntity;
use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;
/**
* Country
*
* @ORMTable(name="countries")
* @ORMEntity(repositoryClass="AppBundleRepositoryCountryRepository")
*/
class Country
{
/**
* @var int
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*
* @AssertType(type="int")
*/
protected $id;
/**
* @var string
*
* @ORMColumn(name="country_name", type="string", length=255, nullable=false)
*
* @AssertNotBlank()
* @AssertType(type="string")
* @AssertLength(max=255)
*/
protected $countryName;
/**
* @var string
*
* @ORMColumn(name="phone_code", type="string", length=10, nullable=false)
*
* @AssertNotBlank()
* @AssertType(type="string")
* @AssertLength(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[]
*
* @ORMOneToMany(targetEntity="Province", mappedBy="country")
*
* @AssertValid()
*/
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.
}
没有找到更好的解决方案:/