У меня есть сущность Cours (это французский для урока), и у этой сущности есть атрибут "prof", который является многозначным отношением с сущностью Prof (учитель по французскому языку). Эта сущность Prof сама по себе расширяет сущность Eleve (ученик) (prof - одиннадцать с большим количеством атрибутов и методов).
Я создал prof и cours с приборами, просто чтобы протестировать свое приложение. Затем, в CourseController, я попытался отправить информацию о своих курсах и профессиях на просмотр. Для этого я загружаю свои курсы, а затем пытаюсь получить доступ к своему профилю через свои курсы.
Когда я пытаюсь показать информацию о курсах, все в порядке. Но когда я пытаюсь получить доступ к проф, больше ничего не работает. Я получил сообщение об ошибке, в котором говорится, что столбец идентификатора не существует, и когда я пытаюсь сбросить проф, он сообщает, что isInitialized имеет значение false, а все атрибуты равны нулю.
Я обнаружил другой стековый поток (или другойфорумы) темы с похожими проблемами, где люди объясняют, что symfony выполняет ленивую загрузку, и не загружает связанную сущность таким образом, что это происходит быстрее. Но все предложенные решения не работают или не являются хорошим выбором в моем случае.
Одним из решений, по-видимому, является установка выборки на рвение в моих отношениях со многими пользователями. Но проблема в том, что сам проф имеет много многозначных, многозначных или других отношений, и каждая из этих сущностей должна разрешать доступ к связанным сущностям (таким образом, извлечение тоже нетерпеливо), и поэтому каждый раз, когда я хочу получить сущность, яБуду загружать всю базу данных. И я просто хочу загрузить то, что мне нужно, что изменится в каждом контроллере и каждом методе.
Другое предлагаемое решение - вызвать некоторые методы моего связанного объекта (в данном случае проф), чтобы сообщить доктрине, что нам нужночтобы получить к нему доступ, таким образом, доктрина загрузить его. Но этот результат снова за исключением (сообщающий столбец id не найден).
в CoursController:
/**
* @Route("/cours/{slug}", name="presentationCours")
*/
public function presentationCours(Cours $cours)
{
$prof = $cours->getProf();
// $prof->getLogin(); THIS result with exception
dump($prof); // THIS shows all null values
die();
return $this->render('cours/presentation.html.twig', [
"cours" => $cours,
"prof" => $prof
]);
}
примечание: если вам интересно, как я получаю переменную $ cours, не сообщая symfony гдечтобы найти его, он может найти его просто с помощью пули на маршруте. Это новое в Symfony 4 (не уверен, что это новое, но я думаю). Я уверен, что это работает, я делал это много раз, и дамп ($ cours) отлично работает.
файл ветки:
{% extends 'base.html.twig' %}
{% block title %}{{ cours.nom }}{% endblock %}
{% block body %}
<p>
{{ cours.nom }}
</p>
<p>
{{ cours.description }}
</p>
<p>
{{ prof.login }} {# THIS result with exception #}
</p>
{% endblock %}
часть сущности Eleve (сущности, котораяявляется родителем prof: prof расширяет одиннадцать)
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\EleveRepository")
*/
class Eleve
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $login;
...
}
часть объекта prof:
<?php
namespace App\Entity;
use App\Entity\Eleve;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\ProfRepository")
*/
class Prof extends Eleve
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="text")
*/
private $introduction;
/**
* @ORM\Column(type="text")
*/
private $description;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Cours", mappedBy="prof")
*/
private $cours;
часть объекта cours:
<?php
namespace App\Entity;
use Cocur\Slugify\Slugify;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity(repositoryClass="App\Repository\CoursRepository")
* @ORM\HasLifecycleCallbacks
*/
class Cours
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Prof", inversedBy="cours")
* @ORM\JoinColumn(nullable=false)
*/
private $prof;
вбаза данных с phpmyadmin:
часть таблицы Cours:
часть таблицы prof:
исключение (без дампа):
результат дампа (проф):
Спасибо за ваше время.
РЕДАКТИРОВАТЬ
Проблема решена! Как сказал jeroen, проблема была в наследовании.
Вот что мне удалось сделать, чтобы решить эту проблему:
<?php
namespace App\Entity;
use App\Entity\Prof;
use App\Entity\Eleve;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\InheritanceType;
use Doctrine\ORM\Mapping\DiscriminatorMap;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping\DiscriminatorColumn;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity(repositoryClass="App\Repository\EleveRepository")
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"eleve" = "Eleve", "prof" = "Prof"})
*/
class Eleve
{
Я добавил тип наследования строк, дискриминатор столбца и дискриминатор карты. Это потому, что я выбрал наследование таблицы классов , но вы можете выбрать сопоставленное решение суперкласса или решение для одиночной таблицы .
Для тех, кто, как и я, сделал бы миграцию до изменения классов, у меня возникла проблема, когда я добавил наследование таблиц классов. Доктрина отказалась мигрировать после этого, исключение сказало мне, что была проблема внешнего ключа. Я не уверен, что это хороший способ, но я удалил мои файлы миграции в Symfony (src> migrations), я удалил всю свою базу данных в phpmyadmin, затем в Symfony, используя CLI (интерфейс командной строки, ctrl + ù на окнах иCtrl + `на Mac (слева от ввода на клавиатуре), я сделал:
- bin / console доктрина: база данных: создать
- bin / console make: миграция
- bin / console доктрина: миграции: миграция
и проблема теперь решена. Но опять же, я действительно не уверен, что это хороший способ, просто говорю, что это сработало для меня.