Thursday, April 13, 2017

How to properly persist OneToMany relation with extra columns in Doctrine 2

According to this question I can make relation with extra columns in reference table using additional entity. But I'm stuck with thought how to properly persist relation via User and Company entities in order to avoid creating CompanyUser realation entity outside the main domains.

Examples are simplified

My case

Company Entity

class Company implements CompanyInterface {

  /** @ORM\OneToMany(targetEntity="CompanyUser", mappedBy="company", cascade={"persist", "remove"}) */
  protected $users;

  public function addUser(UserCompanyInterface $userCompany)
  {
    $this->users[] = $userCompany;
    $userCompany->setCompany($this);

    return $this;
  }

  public function removeUser(UserCompanyInterface $userCompany)
  {
    $this->users->removeElement($userCompany);
    $userCompany->removeCompany();
  }

}

User Entity

class User implements UserInterface {

  /** @ORM\OneToMany(targetEntity="CompanyUser", mappedBy="user", cascade={"persist", "remove"}) */
  protected $companies;

  public function addCompany(UserCompanyInterface $userCompany)
  {
    $this->companies[] = $userCompany;
    $userCompany->setUser($this);

    return $this;
   }

   public function removeCompany(UserCompanyInterface $userCompany)
   {
    $this->companies->removeElement($userCompany);
    $userCompany->removeUser();
   }

}

CompanyUser Entity

class CompanyUser implements CompanyInterface, UserInterface, CompanyUserInterface {

  /** @ORM\OneToMany(targetEntity="CompanyUser", mappedBy="company", cascade={"persist", "remove"}) */
  protected $users;

 /**
 * @ORM\ManyToOne(targetEntity="User", inversedBy="companies", cascade={"persist", "remove"})
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 */
  protected $user;

/**
 * @ORM\ManyToOne(targetEntity="Company", inversedBy="users", cascade={"persist", "remove"})
 * @ORM\JoinColumn(name="company_id", referencedColumnName="id")
 */
  protected $company;

/** @ORM\Column(type="integer") */
  protected $accessStatus; // Extra field

  public function setUser(UserInterface $user)
  {
    $this->user = $user;

    return $this;
  }

  public function setCompany(CompanyInterface $company)
  {
    $this->company = $company;

    return $this;
  }

  public function removeUser()
  {
    $this->user = null;

    return $this;
  }

  public function removeCompany()
  {
    $this->company = null;

    return $this;
  }

}

What's the best way to persist this relation?

I suppose to use such kind of methods but I'm not sure it's an appropriate way :(

  // User entity
  public function addCompany(Company $company)
  {
    $companyUser = new CompanyUser();
    $companyUser->setUser($this);
    $companyUser->setCompany($company);

    $this->companies[] = $companyUser;

    return $this;
   }

   public function removeCompany(Company $userCompany)
   {
    /* ??? Using this approach I don't understand how to remove 
       company from collection because collection 
       consists of CompanyUser entities
    */
   }

Really need help because don't have much experience with Doctrine. If you need any extra info, I'll provide it for you.

Thanks a lot!



via Shandur

Advertisement