0

I've likely asked a question like this before but I don't think it was answered fully. This is really bugging me because I honestly cannot understand why this is a problem.

I have two entities, one called Containers.php and one called ContainerType.php - a user can add a Container and select a Type from a drop down (which is generated using the Entity in the form builder). This works, and is saved correctly in the join table. But, if the user goes on to try and edit this later, the drop down is reset (i.e. it cannot find the existing type) and if another type is chosen from the edit form it just adds it into the join table rather than updating so you get two associations.

Here is the mapping for Containers and ContainerType:

/**
 * Containers
 *
 * @ORM\Table(name="containers")
 * @ORM\Entity
 */
class Containers
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="number", type="string", length=255)
     */
    private $number;

    /**
     * @ORM\ManyToMany(targetEntity="ContainerType")
     *
     * @ORM\JoinColumn(name="id", referencedColumnName="container")
     */
    protected $type;


    public function __construct()
    {
        $this->type = new ArrayCollection();
    }

And my setters and getters for Type:

/**
     * Add type
     *
     * @param \AppBundle\Entity\ContainerType $type
     *
     * @return Containers
     */
    public function addType(ContainerType $type)
    {
        $this->type[] = $type;

        return $this;
    }

    /**
     * Set type
     *
     * @param ArrayCollection $type
     *
     * @return Containers
     */
    public function setType($type)
    {
        $this->type[] = $type;

        return $this;
    }

    /**
     * Get type
     *
     * @return ContainerType
     */
    public function getType()
    {
        return $this->type;
    }

Here is the mapping in ContainerType.php:

/**
 * ContainerType
 *
 * @ORM\Table(name="container_type")
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks()
 */
class ContainerType
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="type", type="string", length=255)
     */
    private $type;

    /**
     * @param \AppBundle\Entity\Containers
     *
     * ORM\@ManyToMany(targetEntity="Containers", mappedBy="type")
     */
    protected $container;

My form type for adding / editing containers is as follows:

$builder->add('number' , 'text', array('label' => 'Container Number'));
        $builder->add('type'  , 'entity',
            array(
                'class' => 'AppBundle:ContainerType',
                'label' => 'Container Type',
                'choice_label' => 'type',
                'empty_value' => '-- Please Select --',
                'multiple' => false
            ));
        $builder->add('save', 'submit', array(
            'attr' => array(
                'class' => 'btn btn-material-blue-800 btn-raised',
                'value' => 'Save'
            ),
        ));

As you can see, multiple is set to FALSE which is what I want - I only want to display a drop down with options as only one type can be assigned to a container. If anyone can help me with my mappings (if they are incorrect, though when I run doctrine:schema:validate it seems they are fine) then I would be grateful.

Otherwise, I do not understand why it only works / saves correctly on Edit when I set multiple to true. Surely this is not the only way to do it?

Thanks in advance Michael

6
  • I don´t think you want to be using a ManyToMany relationship for this use case, you need a bidirectional ManyToOne-OneToMany relationship. If you do this, then everything will work as expected Commented Oct 19, 2015 at 9:49
  • I can never get the ManyToOne relationships to work - there is no solid documentation for this so I always use ManyToMany regardless of whether it need many or not. How can I use the ManyToOne without it failing? Commented Oct 19, 2015 at 10:32
  • There is very good documentation for this. Just take a look at the Doctrine docs: doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/… and the Symfony docs: symfony.com/doc/current/book/doctrine.html. And I am sure that if you google it you will find lots of ManyToOne-OneToMany examples Commented Oct 19, 2015 at 10:36
  • This is the documentation I have used, but never really works the way I expect it to. Plus the OneToMany with Join Table example is a ManyToMany example, so I guess they made a mistake. I'll try going through it again though thanks Commented Oct 19, 2015 at 10:46
  • OK, I tried the ManyToOne unidirectional mapping which works correctly - this is actually better as there is no join table now which I guess I didn't really need since a Container can only have one type, thanks :) Commented Oct 19, 2015 at 11:16

1 Answer 1

1

You need to implement this not as a many-to-many relationship but as a many-to-one relationship. See these docs for more info:

http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/association-mapping.html

http://symfony.com/doc/current/book/doctrine.html

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.