You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的关联映射逻辑,建议先配置实体间的一对多关联,再用关联字段查询:

配置实体关联关系

  1. 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;
    }
}
  1. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:44:52