Laravel Basic
Laravel Form
Laravel Database
Laravel Advance
A Has Many Through relationship is used when one model is related to many records of another model through an intermediate model.
👉 Example:
So the connection looks like:
Hospital → Doctors → Patients
Flow diagram
Use this command to generate a migration for creating a tables:
php artisan make:migration create_has_many_through_tables
public function up(): void
{
// Hospitals table
Schema::create('hospitals', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
// Doctors table
Schema::create('doctors', function (Blueprint $table) {
$table->id();
$table->foreignId('hospital_id')->constrained()->onDelete('cascade');
$table->string('name');
$table->timestamps();
});
// Patients table
Schema::create('patients', function (Blueprint $table) {
$table->id();
$table->foreignId('doctor_id')->constrained()->onDelete('cascade');
$table->string('name');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('patients');
Schema::dropIfExists('doctors');
Schema::dropIfExists('hospitals');
}
Run Migration
php artisan migrate
| id | name | created_at | updated_at |
|---|
| id | name | hospital_id | created_at | updated_at |
|---|
| id | name | doctor_id | created_at | updated_at |
|---|
doctors.hospital_id is a foreign key referencing hospitals.id.patients.doctor_id is a foreign key referencing doctors.id.Generate a model with Artisan:
php artisan make:model Hospital php artisan make:model Doctor php artisan make:model Patient
This generates 3 files Hospital.php , Doctor.php and Patient.php
namespace App\Models;
use App\Models\Doctor;
use App\Models\Patient;
use Illuminate\Database\Eloquent\Model;
class Hospital extends Model
{
protected $fillable = ['name'];
// HasManyThrough: Hospital → Doctors → Patients
public function patients()
{
return $this->hasManyThrough(
Patient::class, // Final model
Doctor::class, // Intermediate model
'hospital_id', // Foreign key on doctors
'doctor_id', // Foreign key on patients
'id', // Local key on hospitals
'id' // Local key on doctors
);
}
public function doctors()
{
return $this->hasMany(Doctor::class);
}
}
namespace App\Models;
use App\Models\Patient;
use App\Models\Hospital;
use Illuminate\Database\Eloquent\Model;
class Doctor extends Model
{
protected $fillable = ['name', 'hospital_id'];
public function hospital()
{
return $this->belongsTo(Hospital::class);
}
public function patients()
{
return $this->hasMany(Patient::class);
}
}
namespace App\Models;
use App\Models\Doctor;
use Illuminate\Database\Eloquent\Model;
class Patient extends Model
{
protected $fillable = ['name', 'doctor_id'];
public function doctor()
{
return $this->belongsTo(Doctor::class);
}
}
use App\Models\Patient; use App\Models\Hospital; use App\Models\Doctor; // Create a Hospital $hospital = Hospital::create(['name' => 'City Care']); // Create Doctor under Hospital $doctor = Doctor::create([ 'hospital_id' => $hospital->id, 'name' => 'Dr. John' ]); // Assign Patient to Doctor $patient = Patient::create([ 'doctor_id' => $doctor->id, 'name' => 'Alice' ]);
| id | name | created_at | updated_at |
|---|---|---|---|
| 1 | City Care | 2025-08-25 14:55:55 | 2025-08-25 14:55:55 |
| id | name | hospital_id | created_at | updated_at |
|---|---|---|---|---|
| 1 | Dr. John | 1 | 2025-08-25 14:55:55 | 2025-08-25 14:55:55 |
| id | name | doctor_id | created_at | updated_at |
|---|---|---|---|---|
| 1 | Alice | 1 | 2025-08-25 14:55:55 | 2025-08-25 14:55:55 |
use App\Models\Patient;
use App\Models\Hospital;
use App\Models\Doctor;
// Get Hospital's Doctors
$hospital = Hospital::find(1);
foreach ($hospital->doctors as $doctor) {
echo $doctor->name;
}
// Get Hospital's Patients through Doctors
$hospital = Hospital::find(1);
foreach ($hospital->patients as $patient) {
echo $patient->name;
}
// Get Doctor with Patients
$doctor = Doctor::find(1);
foreach ($doctor->patients as $patient) {
echo $patient->name;
}
use App\Models\Patient;
use App\Models\Hospital;
use App\Models\Doctor;
// Update Patient
$salary = Patient::where('doctor_id', 1)->first();
$salary->update(['name' => 'kenny']);
// Or directly
$hospital = Hospital::find(1);
$hospital->patients()->where('id', 1)->update(['name' => 'Alice Updated']);
use App\Models\Patient;
use App\Models\Hospital;
use App\Models\Doctor;
// Delete Patient
$patient = Patient::first();
$patient->delete();
// Delete Patient via Doctor using hasMany
$doctor = Doctor::first();
$doctor->patients()->where('id', 1)->delete();
// Delete Doctor (will cascade Patients also if set cascade)
$doctor = Doctor::first();
$doctor->delete();
// Delete Hospital (cascade removes Doctors & their Patients)
$hospital = Hospital::first();
$hospital->delete();
use App\Models\Patient;
use App\Models\Hospital;
use App\Models\Doctor;
// Get Hospital's Doctors
$hospital = Hospital::with('doctors')->find(1);
foreach ($hospital->doctors as $doctor) {
echo $doctor->name;
}
// Get Hospital's Patients through Doctors
$hospital = Hospital::with('patients')->find(1);
foreach ($hospital->patients as $patient) {
echo $patient->name;
}
// Get Doctor with Patients
$doctor = Doctor::with('patients')->find(1);
foreach ($doctor->patients as $patient) {
echo $patient->name;
}
Always use with() when fetching related data in bulk.