I'm still kind of new to api platform. I have two classes a User and a Company. A user has a company. When using the api platform post operation on users it is not setting existing companies or creating new companies. Instead it tries to persist the user with comapny set to NULL which obviously fails. I've included my code and json request body below. Any help is greatly appreciated.
/**
* @ApiResource(
* collectionOperations={
* "get"={
* "normalization_context"={
* "groups"={"get"}
* }
* },
* "post"={
* "denormalization_context"={
* "groups"={"post"}
* },
* "normalization_context"={
* "groups"={"get"}
* }
* }
* },
* itemOperations={
* "get"={
* "normalization_context"={
* "groups"={"get"}
* }
* },
* "put"={
* "denormalization_context"={
* "groups"={"put"}
* },
* "normalization_context"={
* "groups"={"get"}
* }
* },
* "delete"
* },
* subresourceOperations={
* "api_companies_users_get_subresource"={
* "method"="GET",
* "normalization_context"={
* "groups"={"get-company-users"}
* }
* }
* }
* )
* @ORM\Entity(repositoryClass=UserRepository::class)
* @UniqueEntity("code")
* @UniqueEntity("username")
* @UniqueEntity("email")
*/
class User implements UserInterface
{
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
* @ApiProperty(identifier=false)
*/
private $id;
/**
* @ORM\Column(type="guid", unique=true)
* @ApiProperty(identifier=true)
*/
private $code;
/**
* @ORM\Column(type="string", length=255, unique=true)
* @Assert\NotBlank()
* @Assert\Length(min="6", max="255")
* @Groups({"get", "post", "put", "get-company-users"})
*/
private $username;
/**
* @ORM\Column(type="string", length=255)
* @Assert\Regex(
* pattern="/(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*()_+\-=\[\]{};':\x22\\|,.<>\/?]).{7,}/",
* message="Password must be at least 8 characters long and contain at least one digit, one uppercase letter, one lowercase letter, and one special character",
* groups={"post"}
* )
* @Groups({"post"})
*/
private $password;
/**
* @ORM\Column(type="array")
*/
private $roles = ['ROLE_USER'];
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank()
* @Assert\Length(min="1", max="255")
* @Groups({"post", "put"})
*/
private $fname;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank()
* @Assert\Length(min="1", max="255")
* @Groups({"post", "put"})
*/
private $lname;
/**
* @ORM\Column(type="string", length=255, unique=true)
* @Assert\NotBlank()
* @Assert\Email()
* @Assert\Length(max="255")
* @Groups({"get", "post", "put"})
*/
private $email;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Company", inversedBy="users")
* @ORM\JoinColumn(nullable=false)
* @Groups({"get", "post"})
* @Assert\NotNull()
*/
private $company;
public function __construct()
{
$this->code = Uuid::v4()->toRfc4122();
}
public function getId(): ?int
{
return $this->id;
}
public function getCode(): ?string
{
return $this->code;
}
public function getUsername(): ?string
{
return $this->username;
}
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
public function getPassword(): ?string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getRoles(): ?array
{
return $this->roles;
}
public function setRoles(array $roles): self
{
$this->roles = $roles;
return $this;
}
public function getFname(): ?string
{
return $this->fname;
}
public function setFname(string $fname): self
{
$this->fname = $fname;
return $this;
}
public function getLname(): ?string
{
return $this->lname;
}
public function setLname(string $lname): self
{
$this->lname = $lname;
return $this;
}
/**
* @Groups({"get", "get-company-users"})
*/
public function getFullName(): string
{
return $this->fname . ' ' . $this->lname;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getCompany(): ?Company
{
return $this->company;
}
public function setCompany(Company $company): self
{
$this->company = $company;
return $this;
}
public function getSalt()
{
if ($this->email) {
return $this->email;
}
return '';
}
public function eraseCredentials()
{
}
}
/**
* @ApiResource(
* collectionOperations={
* "get",
* "post"={
* "denormalization_context"={
* "groups"={"post"}
* }
* }
* },
* itemOperations={
* "get"={
* "normalization_context"={
* "groups"={"get-company-users"}
* }
* },
* "put"={
* "denormalization_context"={
* "groups"={"put"}
* },
* "normalization_context"={
* "groups"={"get"}
* }
* },
* "delete"
* }
* )
* @ORM\Entity(repositoryClass=CompanyRepository::class)
* @UniqueEntity("code")
* @UniqueEntity("name")
*/
class Company
{
const APP_COMPANY_NAME = 'AppointmentSetter';
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
* @ApiProperty(identifier=false)
*/
private $id;
/**
* @ORM\Column(type="guid", unique=true)
* @ApiProperty(identifier=true)
*/
private $code;
/**
* @ORM\Column(type="string", length=255, unique=true)
* @Assert\NotBlank()
* @Assert\Length(min="2", max="255")
* @Groups({"get", "post", "put", "get-company-users"})
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="company")
* @ApiSubresource()
* @Groups({"get-company-users", "get"})
*/
private $users;
public function __construct()
{
$this->users = new ArrayCollection();
$this->code = Uuid::v4()->toRfc4122();
}
public function getId(): ?int
{
return $this->id;
}
public function getCode(): ?string
{
return $this->code;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getUsers(): Collection
{
return $this->users;
}
public function setUsers(Collection $users): self
{
$this->users = $users;
return $this;
}
public function addUser(User $user): self
{
$this->users->add($user);
return $this;
}
public function removeUser(User $user): self
{
$this->users->removeElement($user);
return $this;
}
}
and the json
{
"username": "newuser",
"email": "newuser@example.com",
"fname": "John",
"lname": "Doe",
"password": "********",
"company": {
"@id": "/api/companies/72366654-0014-4f9c-9a85-ee123dbfd3db"
}
}
More info: I was able to get it to persist the embedded entity by adding cascade persist as indicated in the code snippet below. However I still can't persist a new user without creating a new company as well. It either can't find or doesn't try to find the entity as in the json body above. Any help is appreciated.
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Company", inversedBy="users", cascade={"persist"})
* @ORM\JoinColumn(nullable=false)
* @Groups({"get", "post"})
* @Assert\NotNull()
*/
private $company;