Search code examples
phpsymfonydoctrine-ormmappingsymfony-2.6

Add brands through company, it's possible? How?


I have this two tables (see pics below) mapped as follow:

enter image description here

class Brand
{
    ...

    /**
     * @var Company
     *
     * @ORM\ManyToOne(targetEntity="Company")
     * @ORM\JoinColumn(name="companies_id", referencedColumnName="id")
     */
    protected $company;

}

class Company
{
    ...  
}

I need to add support for add a new Brand from Company but I have not idea in how to achieve this. This are handled through SonataAdminBundle but I think I need to add something else to entities in order to create brands from company but I am not sure what this would be, can I get some help? I am stucked

1st attempt

After get an answer this is how I modify Company entity:

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

class Company
{
    ...

    /**
     * @var Brand
     * @ORM\OneToMany(targetEntity="Brand", mappedBy="company", cascade={"persist"})
     **/
    protected $brands;

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

    ...

    public function getBrands()
    {
        return $this->brands;
    }

    /**
     * Add brands
     *
     * @param Brand $brand
     * @return Brands
     */
    public function addBrand( Brand $brand)
    {
        $this->brands[] = $brand;
        return $this;
    }

    /**
     * Remove brands
     *
     * @param Brand $brand
     */
    public function removeBrand( Brand $brand)
    {
        $this->brands->removeElement($brand);
    }
}

But I am getting this error:

No entity manager defined for class Doctrine\Common\Collections\ArrayCollection

Why is that?


Solution

  • You could try setting up your entities like this:

    class Brand
    {
        /**
         * @var Company
         *
         * @ORM\ManyToOne(targetEntity="Company", inversedBy="brands")
         * @ORM\JoinColumn(name="companies_id", referencedColumnName="id")
         */
        protected $company;
    }
    
    class Company
    {
        /**
         * @var ArrayCollection
         *
         * @OneToMany(targetEntity="Brand", mappedBy="company", cascade={"persist"})
         **/
        protected $brands;
    }
    

    What we're defining here is that new Brands can be created from the Company entity with cascade={"persist"}.

    It's recommended you implement addBrand and removeBrand in Company for direct interaction with the ArrayCollection.

    A simple example of the final functionality:

    $company = $service->getCompany(1); // our company entity
    
    $brand = new Brand();
    $brand->set...
    ...
    
    $company->addBrand($brand);
    
    $entityManager->persist($company);
    

    EDIT

    This is just an example, you may choose not to add with keys or even implement a remove function, but this is a starting point:

    public function addBrand(Brand $brand)
    {
        // key needs to be something that can uniquely identify the brand
        // e.g. name
        $this->getBrands()->set(*key*, $brand);
    
        return $this;
    }
    
    public function removeBrand($key)
    {
        $this->getBrands()->remove($key);
    
        return $this;
    }