Symfony 3.4 / Doctrine 2 один к одному ошибка ассоциации - PullRequest
0 голосов
/ 19 февраля 2019

У меня есть две сущности - User и Cart.Предполагается, что они имеют взаимно-однозначное сопоставление, созданное следующим образом:

User.php:

namespace AppBundle\Entity;

use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\OneToOne(targetEntity="Cart", mappedBy="user")
     */
    private $cart;

    // other things not related to the association
}

Cart.php:

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Class Cart
 * @package AppBundle\Entity
 *
 * @ORM\Entity
 * @ORM\Table(name="Cart")
 */
class Cart
{
    /**
     * @ORM\OneToOne(targetEntity="User", inversedBy="cart")
     */
    private $user;

    // other things not related to the association
}

Я создаю корзину и сохраняю все объекты, когда кто-то пытается просмотреть их корзину в первый раз:

CartController.php:

public function showCartAction()
{
    $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');

    $user = $this->getUser();
    $cart = $user->getCart();

    if ($cart) {
        $items = $cart->getCartItems();
    } else {
        $cart = new Cart();
        $user->setCart($cart);

        $em = $this->getDoctrine()->getManager();
        $em->persist($cart);
        $em->persist($user);
        $em->flush();

        $items = $cart->getCartItems();
    }

    // other unrelated things in the controller
}

При этом тележки создаются, но нетсвязь между User и Cart:

enter image description here

user_id должна иметь идентификатор пользователя.

Любые идеи о том, почемуэто не работает?И возможно ли просто сделать что-то вроде:

public function __construct()
{
    $this->cart = new Cart();
}

В моей User сущности?Будет ли это усиливать ассоциацию?Или это неправильный путь?

1 Ответ

0 голосов
/ 19 февраля 2019

Возможно, вы хотите убедиться, что корзина не может делать ставки, если к ней не привязан пользователь.В отличие от полей, ассоциации обнуляются по умолчанию.Вы должны добавить аннотацию JoinColumn для этого.

 /**
  * @ORM\OneToOne(targetEntity="User", inversedBy="cart")
  * @ORM\JoinColumn(nullable=false)
  */
 private $user;

Другое дело, что, поскольку у вас есть двунаправленная ассоциация, вы должны убедиться, что при вызове $user->setCart($cart) этотакже добавит пользователя в корзину, например, так:

public function setCart(Cart $cart): void
{
    $this->cart = $cart;
    $cart->setUser($this);
}

Поскольку корзина не может быть создана без пользователя, вы также можете вместо этого указать аргумент конструктора:

public function __construct(User $user)
{
    $this->user = $user;
    $user->setCart($this);
}

Таким образом, вы можете опустить метод setUser() в корзине, гарантирующий, что никто не поменяет владельца корзины случайно.

С последним вам, возможно, даже не придется ссылаться на пользователя, так кактележка является владельцем, но для обеспечения согласованного состояния обоих объектов я всегда буду делать это, когда у вас двунаправленная связь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...