ManyToOne JoinColumn (not nullable) not showing form error if `0` submitted with custom form field

StackOverflow https://stackoverflow.com/questions/23338384

  •  10-07-2023
  •  | 
  •  

Question

I have two classes with a bidirectional relationship: Player and Team Each player must have exactly one team and each team can have many players.

When I use the default form field (select) and I submit 0 (by manually editing the HTML) the form error shows correctly. However if I use a custom form field type and submit 0 there's no form error but an exception:

Catchable Fatal Error: Argument 1 passed to ...\Entity\Player::setTeam() must be an instance of ...\Entity\Team, null given, called in ...\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php on line 360 and defined in ...\Entity\Player.php line 58

How do I show a normal form error instead of this exception?

My classes are straighforward (only the relevant parts posted):

Team.php

class Team {
    /**
     * @ORM\OneToMany(targetEntity="...\Entity\Player", mappedBy="team")
     */
    protected $players;
}

Player.php

class Player {

    /**
     * @var Team
     *
     * @ORM\ManyToOne(targetEntity="...\Entity\Team", inversedBy="players")
     * @ORM\JoinColumn(name="team_id", referencedColumnName="id", nullable=false)
     * @Assert\Valid
     */
    protected $team;

    /**
     * Set team
     *
     * @param Team $team
     * @return Player
     */
    public function setTeam(Team $team) {
        $this->team = $team;

        return $this;
    }

    /**
     * Get team
     *
     * @return Team
     */
    public function getTeam() {
        return $this->team;
    }
}

The reverseTransform function of my DataTransformer looks like this:

public function reverseTransform($value)
{
    if(!$value)
    {
        return $this->multiple ? array() : 0;
    }

    //... get entity
}
Was it helpful?

Solution

If you have created a custom form field with a custom data transformer, it is your responsibility to validate client datas. To get the generic message (This value is not valid), you need to throw a TransformationFailedException in your data transformer. Then, everything will be handled by the form component.

EDIT: By default majority of the data transformers in the Symfony core, converts a blank value to null. The responsibility of the data transformer is to convert client data to model data and eventually to detect major error like non-acceptable value for a choice list or missing data in case of datetime field, etc. It is not to validate the data which is the resposibility of the validator component. Then, it lets the validator component make the final validation which is often more complex than a simple data transformer. IMHO, you're currently mixing data transfomer and validation concern.

EDIT: Additionally, you need to allow in your domain object what the data transformer return itself (here, the null value).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top