Home > Software design >  Laravel hasOne through method using Laravel 9
Laravel hasOne through method using Laravel 9

Time:04-04

What I'm trying to achieve. I dealing with 4 tables:

  1. branches (id(PK), branch_name)
  2. staff (id(PK), staff_name)
  3. branch_heads(staff_id(FK -staff),branch_id(FK -branch))

Rules

  1. Staff belongs to a branch
  2. branch has many staff
  3. Each branch is managed by one staff

Below is my code for Branch Model

<?php

namespace App\Models\CompanyStructure;

use App\Models\StaffManagement\Staff;
use Illuminate\Database\Eloquent\Model;
use App\Models\CompanyStructure\BranchHead;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Branch extends Model
{
    use HasFactory;
    protected $fillable = [
        'branch_name',
    ];

    public function staff()
    {
        return $this->hasMany(Staff::class);
    }

    public function branchhead()
    {
        return $this->hasOne(BranchHead::class);
    }
}

Below is my code for Staff Model

<?php

namespace App\Models\StaffManagement;

use App\Models\CompanyStructure\Branch;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Staff extends Model
{
    use HasFactory;
    protected $table = 'staff';
    protected $fillable = [
        'staff_name',
    ];

    public function branch()
    {
        return $this->belongsTo(Branch::class);
    }

}

Below is my code for BranchHead Model

<?php

namespace App\Models\CompanyStructure;

use App\Models\StaffManagement\Staff;
use App\Models\CompanyStructure\Branch;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class BranchHead extends Model
{
    use HasFactory;

    protected $fillable = [
        'staff_id',
        'branch_id',
    ];

    public function staff()
    {
        return $this->hasOne(Staff::class);
    }

    public function branch()
    {
        return $this->hasOne(Branch::class);
    }

}

results from tinker:

Branch::find(1)->branchhead -- gives me the results of the staff_id that manages a particular branch_id. But can't go beyond that level to get which staff_name that manages which branch.

I'm using Laravel 9 and PHP 8.1

How can I get the staff_names?

CodePudding user response:

The relation between staff and branches is a one to many with a special staff entity that can be the branch head.

  • branches (id(PK), branch_name)
  • staff (id(PK), branch_id(FK -branch), staff_name, is_head_branch)
class Branch extends Model
{
    use HasFactory;
    protected $fillable = [
        'branch_name',
    ];

    public function staff()
    {
        return $this->hasMany(Staff::class);
    }

    public function branchhead()
    {
        return $this->hasOne(staff::class)->where('is_head_branch',1);
    }
}

Add in comment any issue you have with this structure. I'll edit in the response.

To get all staff from a branch use

$branch->staff

it will include the head branch staff member (you can check on the flag $staffMember->is_head_branch == 1)

To get all BranchHeads with their associated branch or the other way around, do it like this

$headBranchs = Staff::where('is_head_branch', 1)->with('branch')->get();
//or
$branchs = Branch::with('branchhead')->get();
  • Related