5.0 KiB
فیکس نمایش دکتر در شهر از طریق کلینیک
پروژه
clinicpro (backend)
زمینه
دکتری که هیچ آدرس و city مستقیمی ندارد اما به یک کلینیک وصل است، در سایت عمومی (nobat724_front) در شهر آن کلینیک نمایش داده نمیشود. علت: query فیلتر city فقط روی d.cities (جدول doctor_cities) کار میکند و Clinic.cityId را نادیده میگیرد.
مشکل
DoctorRepository::findWithFilters() فیلتر city:
// clinicpro/src/Doctor/Repository/DoctorRepository.php خط ۵۶-۵۸
if (!empty($filters['city'])) {
$qb->andWhere('ci.id = :city')->setParameter('city', (int) $filters['city']);
}
ci از leftJoin('d.cities', 'ci') میآید — جدول doctor_cities. اگر دکتر در این جدول ردیفی نداشته باشد (یعنی هیچ city مستقیم ندارد)، حتی اگر عضو کلینیکی با همان city باشد، از نتایج حذف میشود.
ساختار مرتبط
// Doctor Entity
#[ORM\ManyToMany(targetEntity: City::class)]
#[ORM\JoinTable(name: 'doctor_cities')]
private Collection $cities; // جدول doctor_cities
// Clinic Entity
#[ORM\Column(name: 'city_id', type: 'integer', nullable: true)]
private ?int $cityId = null; // FK به categories.id
#[ORM\ManyToMany(targetEntity: Doctor::class)]
#[ORM\JoinTable(name: 'clinic_doctors')]
private Collection $doctors; // جدول clinic_doctors
فایلهای مرتبط
| فایل | نقش |
|---|---|
clinicpro/src/Doctor/Repository/DoctorRepository.php |
findWithFilters() — باید تغییر کند |
clinicpro/src/Doctor/Controller/DoctorController.php |
صدا زننده findWithFilters |
clinicpro/src/Clinic/Entity/Clinic.php |
cityId و doctors collection |
clinicpro/src/Doctor/Entity/Doctor.php |
cities collection |
وضعیت فعلی
// DoctorRepository.php — findWithFilters()
$qb = $this->createQueryBuilder('d')
->leftJoin('d.specialties', 's')
->leftJoin('d.provinces', 'pr')
->leftJoin('d.cities', 'ci')
->distinct();
// ...
if (!empty($filters['city'])) {
$qb->andWhere('ci.id = :city')->setParameter('city', (int) $filters['city']);
}
وظایف
۱. گسترش فیلتر city به clinic city
در findWithFilters() join کلینیک را اضافه کن و شرط city را تغییر بده تا هم doctor_cities هم clinic.city_id را پوشش دهد:
$qb = $this->createQueryBuilder('d')
->leftJoin('d.specialties', 's')
->leftJoin('d.provinces', 'pr')
->leftJoin('d.cities', 'ci')
->leftJoin(Clinic::class, 'cl', Join::WITH, 'd MEMBER OF cl.doctors') // ← اضافه
->distinct();
// ...
if (!empty($filters['city'])) {
$qb->andWhere('ci.id = :city OR cl.cityId = :city')
->setParameter('city', (int) $filters['city']);
}
همچنین فیلتر state را هم بررسی کن — اگر d.provinces هم خالی باشد، باید از استان کلینیک گرفته شود. اما برای این باگ، city اولویت دارد.
۲. بررسی فیلتر state مشابه
// فعلی:
if (!empty($filters['state'])) {
$qb->andWhere('pr.id = :state')->setParameter('state', (int) $filters['state']);
}
// باید:
// اگر کلینیک دارد، province آن کلینیک را هم در نظر بگیر
// اما Clinic فقط cityId دارد، نه provinceId مستقیم
// → از category join برای گرفتن province شهر کلینیک استفاده کن یا فعلاً فقط city را فیکس کن
۳. import لازم
در بالای DoctorRepository.php اضافه کن:
use App\Clinic\Entity\Clinic;
use Doctrine\ORM\Query\Expr\Join;
(اگر Join از قبل import نشده)
۴. تست
ddev exec php bin/console debug:router | grep "api/v1/doctors"
# endpoint: GET /api/v1/doctors?city=<city_id>
# تست: یک دکتر که فقط از طریق کلینیک در شهر X است را با ?city=X جستجو کن
# باید در نتایج ظاهر شود
نکات مهم
Clinic.cityIdیک integer FK است بهcategories.id(جدول categories با bundle='city') — نه یک relation object. پسcl.cityId = :cityدرست است (نهcl.city.id).leftJoinبرای کلینیک لازم است نهinnerJoin— دکتری که اصلاً عضو هیچ کلینیکی نیست هم باید در نتایج بماند (اگر city مستقیم دارد).OR cl.cityId = :cityممکن است باDISTINCTمشکل ایجاد کند — اگر دکتر هم city مستقیم دارد هم عضو کلینیک در همان city است،DISTINCTآن را یکبار نمایش میدهد.- migration لازم نیست — فقط query تغییر میکند.
- بعد از تغییر،
docs/api/doctor.mdرا update کن (رفتار فیلتر city تغییر کرده).