Symfony: Как настроить встроенную форму для создания нового дочернего объекта?

Я создаю страницу управления пользователями, на которой создаю или редактирую пользователей.

Пользователь состоит из двух сущностей, пользователь и профиль, которые связаны отношениями один к одному (я бы слился, но не могу по историческим причинам).

/ * User.php - Класс сущности

/**
 * @var Profile
 * @Assert\Type(type="App\Entity\Profile")
 * @Assert\Valid()
 * @ORM\OneToOne(targetEntity="Profile", mappedBy="user", cascade={"persist"})
 */
private $profile;

/ * Profile.php - класс сущности профиля

/**
 * @var \App\Entity\User
 *
 * @ORM\OneToOne(targetEntity="App\Entity\User", inversedBy="profile")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 * })
 */
private $user;

Я построил две формы.

Одна из форм - это форма профиля, которая содержит все основные поля профиля (first_name, last_name, email), но не содержит явно поле отношения (user_id).

Другая форма - это форма пользователя, которая содержит основные поля пользователя (имя пользователя, пароль), а также форму профиля.

    $builder->add('profile', ProfileForm::class);

Когда я использую эту форму для редактирования, все работает нормально, и изменения обоих объектов сохраняются. Но когда я пытаюсь использовать форму для создания нового пользователя, это терпит неудачу, говоря, что мне не хватает user_id.

    SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'user_id' cannot be null

Похоже, это должно сработать, но я что-то упускаю.


person Geoff Maddock    schedule 22.02.2018    source источник
comment
Обычно такая проблема возникает, если Profile :: setUser никогда не вызывается.   -  person Cerad    schedule 23.02.2018
comment
Мне непонятно, где это называется. Как только я проверяю форму, я вызываю persist для пользовательского объекта, и здесь возникает ограничение целостности. Я думал, что конфигурация отношения пользователя и профиля автоматически вызовет этот установщик. Я пропустил шаг?   -  person Geoff Maddock    schedule 23.02.2018
comment
Любопытно, что после проверки я добавил явный вызов setUser к методу more store: $ user- ›getProfile () -› setUser ($ user); И это сработало. По-прежнему чувствую, что это нужно вызывать в другом месте.   -  person Geoff Maddock    schedule 23.02.2018
comment
Обычно вы вызываете его в User :: setProfile (). Распространенная ошибка - думать, что доктрина автоматически связывает два объекта во время создания.   -  person Cerad    schedule 23.02.2018
comment
Это привело меня туда. Спасибо.   -  person Geoff Maddock    schedule 23.02.2018


Ответы (1)


Спасибо @Cerad за этот ответ. Я не устанавливал ссылку в классе setProfile объекта User.

/**
 * Set profile
 *
 * @param \App\Entity\Profile $profile
 *
 * @return SfGuardUser
 */
public function setProfile(\App\Entity\Profile $profile = null)
{
    $this->profile = $profile;
    $this->profile->setUser($this);  // Adding this line fixed my issue

    return $this;
}
person Geoff Maddock    schedule 23.02.2018