Symfony 6关联表报错:Patients类无patient属性或对应公共方法
问题解决
错误根源
Twig模板中错误使用item.patient.id,但控制器DQL查询返回的结果数组里,Patients实体的别名是patients而非patient,且实体本身不存在patient属性,直接触发报错。
步骤1:快速修复Twig模板
将模板中所有item.patient改为item.patients,匹配DQL里的实体别名:
{% for item in data %} <tr> <td>{{ item.patients.id }}</td> <td><i class="fas fa-user-nurse fs-5"></i> {{ item.patients.name }}</td> <td>{{ item.patientsInfo.nationality }}</td> <td>{{ item.patients.unhcrID }}</td> <td>No</td> <td>{{ item.patients.creationDate|date('Y-m-d') }}</td> <td>None</td> <td> <a class="btn btn-primary" role="button">More</a> <a class="btn btn-danger" role="button">Delete</a> </td> </tr> {% endfor %}
步骤2:规范关联查询(推荐)
手动通过WHERE关联表不符合Doctrine的关联映射逻辑,建议先配置实体间的一对多关联,再用关联字段查询:
配置实体关联关系
- Patients实体(一对多的主端):
// App\Entity\Patients.php namespace App\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: PatientsRepository::class)] class Patients { // 其他属性... #[ORM\OneToMany(targetEntity: PatientsInformation::class, mappedBy: 'patient')] private Collection $patientsInformations; public function __construct() { $this->patientsInformations = new ArrayCollection(); } public function getPatientsInformations(): Collection { return $this->patientsInformations; } }
- PatientsInformation实体(多对一的从端):
// App\Entity\PatientsInformation.php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: PatientsInformationRepository::class)] class PatientsInformation { // 其他属性... #[ORM\ManyToOne(targetEntity: Patients::class, inversedBy: 'patientsInformations')] #[ORM\JoinColumn(name: 'patientID', referencedColumnName: 'id')] private ?Patients $patient = null; public function getPatient(): ?Patients { return $this->patient; } public function setPatient(?Patients $patient): self { $this->patient = $patient; return $this; } }
修改控制器查询代码
用关联字段替代手动WHERE条件进行JOIN:
#[Route('/admin/patients', name: 'app_patients')] public function patients(PatientsRepository $patients, EntityManagerInterface $entityManager): Response { $query = $entityManager->createQuery( 'SELECT patients, patientsInfo FROM App\Entity\Patients patients JOIN patients.patientsInformations patientsInfo' ); $data = $query->getResult(); return $this->render('main/tables.html.twig', ['data' => $data]); }
更简洁的Repository封装(推荐)
在PatientsRepository中封装查询逻辑,代码更易维护:
// App\Repository\PatientsRepository.php namespace App\Repository; use App\Entity\Patients; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; /** * @extends ServiceEntityRepository<Patients> */ class PatientsRepository extends ServiceEntityRepository { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, Patients::class); } public function findAllWithInformations() { return $this->createQueryBuilder('p') ->leftJoin('p.patientsInformations', 'pi') ->addSelect('pi') ->getQuery() ->getResult(); } }
控制器直接调用封装方法:
#[Route('/admin/patients', name: 'app_patients')] public function patients(PatientsRepository $patients): Response { $data = $patients->findAllWithInformations(); return $this->render('main/tables.html.twig', ['data' => $data]); }
此时Twig模板可调整为遍历实体自带的关联集合(适配一对多的多数据场景):
{% for patient in data %} {% for info in patient.patientsInformations %} <tr> <td>{{ patient.id }}</td> <td><i class="fas fa-user-nurse fs-5"></i> {{ patient.name }}</td> <td>{{ info.nationality }}</td> <td>{{ patient.unhcrID }}</td> <td>No</td> <td>{{ patient.creationDate|date('Y-m-d') }}</td> <td>None</td> <td> <a class="btn btn-primary" role="button">More</a> <a class="btn btn-danger" role="button">Delete</a> </td> </tr> {% endfor %} {% endfor %}
内容的提问来源于stack exchange,提问作者hareth py
相关产品推荐
相关产品推荐

