I have two entities User and UserSettings.
I would like to add new user entry with settings entry that are linked by OneToOne relation.
Entity User
namespace App\Entity;
use ApiPlatform\Core\Annotation as API;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation as Serializer;
/**
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
*
* @API\ApiResource(
* itemOperations={
* "GET"={
* "normalization_context"={"groups"={"user-get"}}
* }
* },
* collectionOperations={
* "GET"={
* "normalization_context"={"groups"={"user-get"}}
* },
* "POST"={
* "denormalization_context"={"groups"={"user-post"}}
* },
* }
* )
*/
class User
{
/**
* @var int
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Serializer\Groups({"user-get"})
*/
private $id;
/**
* @var string
* @ORM\Column(type="string", length=64, nullable=false)
* @Serializer\Groups({"user-get", "user-post"})
*/
private $name;
/**
* @var UserSettings
* @ORM\OneToOne(targetEntity="UserSettings", mappedBy="user", cascade={"persist", "remove"})
* @Serializer\Groups({"user-get", "user-post"})
* @API\ApiSubresource()
*/
private $settings;
}
Entity UserSettings
namespace App\Entity;
use ApiPlatform\Core\Annotation as API;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation as Serializer;
/**
* @ORM\Entity(repositoryClass="App\Repository\UserSettingsRepository")
*
* @API\ApiResource(
* itemOperations={"GET"},
* collectionOperations={"POST"},
* )
*/
class UserSettings
{
/**
* @var int
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Serializer\Groups({"user-get"})
*/
private $id;
/**
* @var User
* @ORM\OneToOne(targetEntity="User", inversedBy="settings")
* @ORM\JoinColumn(onDelete="CASCADE", nullable=true)
*/
private $user;
/**
* @var string
* @ORM\Column(type="string")
* @Serializer\Groups({"user-get", "user-post"})
*/
private $test;
}
POST request data
{
"@type": "User",
"name": "admin",
"settings": {
"@type": "UserSettings",
"test": "test string"
}
}
When I try to POST in database is created two entry in both tables but without relation. Unfortunately user_id field in UserSettings table contains null. Relation is not created.
RAW SQL queries log:
INSERT INTO user (name) VALUES (?) {"1":"admin"}
INSERT INTO user_settings (test, user_id) VALUES (?, ?) {"1":"test string","2":null}
But I expect that will be created entry in User table and after that will be created UserSettings entry by using id of new user for set this value into user_id field as OneToOne relation.
Use this:
<?php
class User {
public function setSettings(UserSettings $settings) {
$settings->setUser($this);
$this->settings = $settings;
}
}
@soyuka Thanks ! Your advice is helpful
Working approach
/**
* @return UserSettings
*/
public function getSettings(): ?UserSettings
{
return $this->settings;
}
/**
* @param UserSettings $settings
*
* @return User
*/
public function setSettings(UserSettings $settings): User
{
$this->settings = $settings;
if ($settings->getUser() !== $this) {
$settings->setUser($this);
}
return $this;
}
/**
* @return User
*/
public function getUser(): ?User
{
return $this->user;
}
/
* @param User $user
* @return UserSettings
*/
public function setUser($user): UserSettings
{
$this->user = $user;
if ($user->getSettings() !== $this) {
$user->setSettings($this);
}
return $this;
}
I have same problem but when i do a PUT with null data (to delete relation), after a post with some settings example:
FIRST, A POST
{
"@type": "User",
"name": "admin",
"settings": {
"@type": "UserSettings",
"test": "test string"
}
}
AFTER, A PUT
{
"@type": "User",
"name": "adminEdited",
"settings": null
}
The field "name" is edited with "adminEdited", but the settings are not removed.
Most helpful comment
Use this: