Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

toby's avatar
Level 31

Intermediate/pivot table w/ three foreign keys

Hi everyone,

In a current project, I try to relate models via an intermediate/pivot table with three foreign keys. The models which are connected through this pivot tables are:

UseCase
=======
id
name

Hazard
======
id
name

Action
======
id
name

the pivot table looks like this:

knots
-----
use_case_id
hazard_id
action_id

The scenario is the following: A UseCase can have many Hazards and (the combination of) a UseCase and a Hazard can have many Actions.

But I need to display each relation from every model, therefore I used the following methods:

class UseCase extends Model
{
    public function hazards()
    {
        return $this->belongsToMany(Hazard::class, 'knots')
            ->groupBy(['use_case_id', 'hazard_id'])
            ->orderBy('hazards.name')
            ->withPivot('use_case_id', 'hazard_id', 'action_id');
    }

    public function actions()
    {
        return $this->belongsToMany(Action::class, 'knots')
            ->groupBy(['use_case_id', 'action_id'])
            ->orderBy('actions.name')
            ->withPivot('use_case_id', 'hazard_id', 'action_id');
    }
}
class Hazard extends Model
{
    public function useCases()
    {
        return $this->belongsToMany(UseCase::class, 'knots')
            ->groupBy(['hazard_id', 'use_case_id'])
            ->orderBy('use_case.name')
            ->withPivot('use_case_id', 'hazard_id', 'action_id');
    }

    public function actions()
    {
        return $this->belongsToMany(Action::class, 'knots')
            ->groupBy(['hazard_id', 'action_id'])
            ->orderBy('actions.name')
            ->withPivot('use_case_id', 'hazard_id', 'action_id');
    }
}
class Action extends Model
{
    public function hazards()
    {
        return $this->belongsToMany(Hazard::class, 'knots')
            ->groupBy(['action_id', 'hazard_id'])
            ->orderBy('hazards.name')
            ->withPivot('use_case_id', 'hazard_id', 'action_id');
    }

    public function useCases()
    {
        return $this->belongsToMany(UseCase::class, 'knots')
            ->groupBy(['action_id', 'use_case_id'])
            ->orderBy('use_cases.name')
            ->withPivot('use_case_id', 'hazard_id', 'action_id');
    }
}

I used the grouping to remove any duplicates (because it is possible, that the same Action can be assigned to a UseCase but with a different Hazard...)

But now I want to display every UseCase with its Hazards and the according Actions and I really got stuck here :(

Do you have any idea on how to display this relation correctly (w/o duplicated and/or missing Actions [due to the groupBy]?

Thanks in advance and have a nice day!!!

0 likes
0 replies

Please or to participate in this conversation.