Pergunta sobre validation, collections, symfony, doctrine, one-to-many – Symfony2 + Doctrine - Validando uma-para-muitas coleções de entidades

13

Eu tenho um formulário para criar uma nova entidade. Essa entidade tem uma coleção de outras entidades que também são inseridas nesse formulário.

Eu quero usar as opções de validação da entidade na coleção para validar essas entidades, mas isso não funciona. As regras de validação da entidade "principal" (Pessoa) são verificadas, mas as regras de validação das entidades noaddressList coleção (Endereço) não está marcada. Quando insiro informações inválidas nos campos, o formulário enviado é validado com sucesso.

Neste exemplo, a anotação para street não é usada na validação.

<code>class Person 
{
    ...

    /**
     * @ORM\OneToMany(targetEntity="Address", mappedBy="owner", cascade={"persist", "detach"})
     */
    protected $addressList;

    ....
}

class Address
{
    ...
    /**
     * @ORM\ManyToOne(targetEntity="Person", inversedBy="addressList")
     * @ORM\JoinColumn(name="person_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $owner;

    /**
     * @ORM\Column(type="string", length=75)
     * @Assert\MinLength(
     *     limit=3,
     *     message="Street must have atleast {{ limit }} characters."
     * )
     */
    protected $street;

    ...

}
</code>

Como posso obter o formulário para validar as entidades de endereço fornecidas?

Eu consertei isso adicionando'cascade_validation' => true para a matriz degetDefaultOptions() do PersonType. Bramklg

Sua resposta

4   a resposta
14

Eu tive o mesmo problema, mas foi resolvido com:

<code>/**
 * @ORM\OneToMany(
 *  targetEntity="Entity",
 *  mappedBy="mappedEntity",
 *  cascade={"persist" , "remove"}
 * )
 * @Assert\Valid
 */
</code>
Isso validará que cada endereço da lista é válido apenas como entidade de endereço. Mas se você quiser mais algumas validações, veja a resposta @ sergey-polischook abaixo Jekis
@Assert\Valid faz com que ele valide todas as restrições no lado do ManyToOne da coleção e é exatamente o que eu precisava. Armel Larcier
7

Eu uso isso:

<code>use Symfony\Component\Validator\ExecutionContextInterface;

class Person 
{
...

/**
 * @ORM\OneToMany(targetEntity="Address", mappedBy="owner", cascade={"persist", "detach"})
 */
protected $addressList;

....

/**
 * @Assert\Callback
 */
public function validate(ExecutionContextInterface $context)
{
    if (!$this->getAddressList()->count()) {
        $context->addViolationAt(
            'addressList',
            'You must add at least one address',
            array(),
            null
        );
    }
}
}
</code>

http://symfony.com/doc/current/reference/constraints/Callback.html

Adicione também @Assert \ Valid a $ addressList e esta será a solução completa Jekis
5

Basta adicionar a afirmação de anotação como segue

<code>/** 
 * @Assert\Count(
 *      min = "1",
 *      minMessage = "You must specify at least one"
 * )
 * @Assert\Valid 
 * 
 */
protected $name_of_collection_property;
</code>
0

Você também pode usar o "Válido"restrição com o"Todos" restrição :

<code>/**
 * @ORM\OneToMany(targetEntity="Address", mappedBy="owner", cascade={"persist", "detach"})
 * @Assert\All({
 *     @Assert\Valid
 * })
 */

protected $addressList;
</code>
Isso não está mais funcionando com 2.6+, com certeza. tftd
Você tem certeza? Isso me dá "A restrição Válida não pode ser aninhada dentro da restrição Symfony \ Component \ Validator \ Restaints \ All. Você só pode declarar a restrição Válida diretamente em um campo ou método." em 2.1 nurikabe
Eu tive um problema semelhante com 3.3 e @Assert \ Valid () sem o @Assert \ All em torno dele parece funcionar bem. E, obviamente, livrar-se da mensagem de erro "... Válido não pode ser aninhada dentro ... Todos ..." também. Andy Preston
Não tenho mais certeza. Acho que usava o 2.0 naquela época e tive que lidar com um problema semelhante. Se não funcionar, talvez eu deva remover minha resposta. Julien

Perguntas relacionadas