Symfony4 & Doctrine: объединение не работает - PullRequest
0 голосов
/ 28 мая 2018

Я пробую Symfony4, Doctrine & PgSQL. У меня есть Клиенты, у которых много пользователей, у меня есть страница входа и страница профиля (которые только выдают в журнал $ user и $ user-> getCustomer ())

База данных содержит: клиентов:

+----+------------+
| id |    name    |
+----+------------+
|  2 | Customer 1 |
+----+------------+

пользователей:

+----+-------------+----------+--------------------------------------------------------------+-----------+
| id | customer_id | username |                           password                           | is_active |
+----+-------------+----------+--------------------------------------------------------------+-----------+
|  1 |           2 | root     | $2y$12$s.J4LbCNSKk6dssRrS2yteBGpQT192JvayICEv9zVfax3DykvR5yW | t         |
+----+-------------+----------+--------------------------------------------------------------+-----------+

Когда я вхожу в систему и захожу в / profile, я вижу пользователя:

User {#81545 ▼
  -id: 1
  -username: "root"
  -password: "$2y$12$s.J4LbCNSKk6dssRrS2yteBGpQT192JvayICEv9zVfax3DykvR5yW"
  -isActive: true
  -customer: Customer {#81604 ▼
    +__isInitialized__: false
    -id: 2
    -name: null
    -users: null
     …2
  }
}

Но имя клиента пусто.Почему в объекте customer идентификатор установлен правильно, а остальные поля нет?И как я могу получить «полный» объект

Контроллер выглядит так:

    /**
     * @Route("/profile")
     */
    public function profile(): Response
    {
        return $this->render('admin/home.html.twig', array(
                    'me' => $this->getUser(),
                    'customer' => null,
        ));
    }

Но я обновляю контроллер до (только добавьте $ customerRepository-> findOneBy)

    /**
     * @Route("/profile")
     */
    public function profile(\App\Repository\CustomerRepository $customerRepository): Response
    {
        $unused = $customerRepository->findOneBy(['id' => $this->getUser()->getCustomer()->getId()]);

    return $this->render('admin/home.html.twig', array(
                'me' => $this->getUser(),
                'customer' => null,
    ));
}

Теперь поле клиента установлено правильно.Я не понимаю,

Здесь шаблон ветки страницы профиля:

{% extends "base.html.twig" %}
{% block body %}
    <b>Authenticated !</b><br/>
    {{ dump(me) }}
    {{ dump(me.customer) }}
{% endblock %}

Здесь реализация клиента:

namespace App\Accounting;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="customers",schema="test")
 * @ORM\Entity(repositoryClass="App\Repository\CustomerRepository")
 */
class Customer implements \Serializable
{

    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", unique=true)
     */
    private $name;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="customer")
     * @ORM\JoinColumn(name="customer_id", referencedColumnName="id", nullable=true)
     */
    private $users;

    public function __construct()
    {
        $this->users = new \Doctrine\Common\Collections\ArrayCollection();
    }

    // all setters & getters
}

И пользователь:

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;

/**
 * @ORM\Table(name="users",schema="test")
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 */
class User implements UserInterface, \Serializable
{

    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", unique=true)
     */
    private $username;

    /**
     * @ORM\Column(type="string", length=64)
     */
    private $password;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Customer", inversedBy="users")
     * @ORM\JoinColumn(name="customer_id", referencedColumnName="id", nullable=true)
     */
    private $customer;

    // all setters & getters

    public function eraseCredentials()
    { 
    }

    /** @see \Serializable::serialize() */
    public function serialize()
    {
        return serialize(array(
            $this->id,
            $this->username,
            $this->password,
                // see section on salt below
                // $this->salt,
        ));
    }

    /** @see \Serializable::unserialize() */
    public function unserialize($serialized)
    {
        list (
                $this->id,
                $this->username,
                $this->password,
                // see section on salt below
                // $this->salt
                ) = unserialize($serialized, ['allowed_classes' => false]);
    }

}

1 Ответ

0 голосов
/ 30 мая 2018

Это называется отложенная загрузка .Это означает, что отношения ваших объектов не инициализируются, пока вы не потребуете их.Он используется для оптимизации памяти и запросов к базе данных.Вы можете увидеть набор идентификаторов, но также +__isInitialized__: false.При первом обращении к клиенту с помощью вашего $user->getCustomer() метода orm выполнит запрос для извлечения объекта.

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

Так что добавьте это в свой класс пользователя

public function getCustomer(){
    return $this->customer;
}

И всякий раз, когда вам нужен объект "customer", получайте его, используя метод.

...