В Symfony3.4 я пытаюсь объединить две сущности, и если это уже дано, я получил ошибку «повторяющаяся запись». Это делается через отношение Many2Many в доктрине.
Пользователь: компания <---Many2Many---> Компания: пользователи
Как я могу отловить ошибку в действии контроллера, чтобы отреагировать на нее?
Пользовательская сущность:
/**
* @ORM\Table(name = "md_user")
* @ORM\Entity(repositoryClass = "AppBundle\Repository\UserRepository")
* @Vich\Uploadable
* @ApiResource(
* collectionOperations = {
* "get" = {"method" = "GET"},
* "post" = {"method" = "POST"}
* },
* itemOperations = {
* "get" = {"method" = "GET", "access_control_message" = "Sorry, but you are not allowed to do this."},
* "put" = {"method" = "PUT"}
* },
* attributes = {"access_control" = "is_granted('ROLE_USER')"})
* @ORM\AttributeOverrides({
* @ORM\AttributeOverride(name = "usernameCanonical",
* column=@ORM\Column(
* name = "username_canonical",
* length = 191,
* unique = true
* )
* ),
* @ORM\AttributeOverride(name = "emailCanonical",
* column=@ORM\Column(
* name = "email_canonical",
* length = 191,
* unique = false,
* nullable=true
* )
* )
*
* })
*/
class User extends BaseUser
{
public function __construct()
{
parent::__construct();
$this->created = new \DateTime();
$this->company = new ArrayCollection();
$this->roles = array('ROLE_USER');
}
/**
* @ORM\Id
* @ORM\Column(type = "integer")
* @ORM\GeneratedValue(strategy = "AUTO")
*/
protected $id;
/**
* @ORM\ManyToMany(targetEntity = "AppBundle\Entity\Company",inversedBy = "users")
* @ORM\JoinTable(name = "user_comp_comp_user",
* joinColumns = {@ORM\JoinColumn(name = "user_id", referencedColumnName = "id")},
* inverseJoinColumns = {@ORM\JoinColumn(name = "company_id", referencedColumnName = "id")}
* )
*/
protected $company;
/**
* @return mixed
*/
public function getCompany()
{
return $this->company;
}
/**
* @param mixed $company
* @return User
*/
public function setCompany($company)
{
$this->company = $company;
return $this;
}
/**
* @param Company $company
*/
public function addCompany(Company $company)
{
if ($this->company->contains($company)) {
return;
}
$this->company[] =$company;
return $this;
}
/**
* @param Company $company
*/
public function removeCompany(Company $company)
{
if (!$this->company->contains($company)) {
return;
}
$this->company->removeElement($company);
$company->removeUser($this);
}
Юридическое лицо компании:
class Company
{
public function __construct()
{
$this->created = new \DateTime();
$this->users = new ArrayCollection();
}
/**
* @ORM\Id
* @ORM\Column(type = "integer")
* @ORM\GeneratedValue(strategy = "AUTO")
*/
protected $id;
/**
* @ORM\Column(name = "mandant",type = "integer",nullable=true)
*/
protected $mandant;
/**
* @ORM\Column(type = "integer",nullable=true)
*/
protected $customer_group;
/**
* @var \Doctrine\Common\Collections\Collection|Company[]
* @ORM\ManyToMany(targetEntity = "User",mappedBy = "company")
*/
protected $users;
/**
* @return Company[]|\Doctrine\Common\Collections\Collection
*/
public function getUsers()
{
return $this->users;
}
/**
* @param Company[]|\Doctrine\Common\Collections\Collection $users
* @return Company
*/
public function setUsers($users)
{
$this->users = $users;
return $this;
}
/**
* @param User $user
*/
public function addUser(User $user)
{
if ($this->users->contains($user)) {
return;
}
$this->users[] =$user;
return $this;
}
/**
* @param User $user
*/
public function removeUser(User $user)
{
if (!$this->users->contains($user)) {
return;
}
$this->users->removeElement($user);
$user->removeCompany($this);
}
Упрощенное действие контроллера:
$user = $this->getDoctrine()->getRepository(User::class)->find($id);
$company = $this->getDoctrine()->getRepository(Company::class)->find($company_id);
$user->addCompany($company);
try {
$this->getDoctrine()->getManager()->merge($user);
$this->getDoctrine()->getManager()->flush();
}catch (UniqueConstraintViolationException $e) {
return new JsonResponse(array('success' => false,'error'=> $e->getMessage()));
}




Нашел сам.
Чтобы проверить наличие дубликатов перед промывкой, вы можете использовать addCompany() в User.
public function addCompany(Company $company)
{
if ($this->company->contains($company)) {
return;
}
$this->company[] =$company;
return $this;
}
Это проверяет, введена ли уже запись. если нет, то возвращается.
В контроллере это можно сделать так:
if (!$user->addCompany($company)){
return new JsonResponse(array('success' => false,'error'=> 'duplicate entry'));
}
Надеюсь, это кому-то поможет.