-
Notifications
You must be signed in to change notification settings - Fork 0
Relations with 2 link keys
This is how it can be accomplished by using HasManyThrough from Laravel and laravel-crud-wizard’s new type of relation HasManyThrough2LinkTables.
Consider a situation where an user speaks more languages, meaning the user-language pair (2 keys) replaces the user (1 key) in current logic, with the following tables:
users: id
users_languages_pivot: id, user_id, language
users_roles_pivot: id, user_id, language, role_id
roles: id
The relation defined in Role to UserLanguagePivot model would look like this:
/**
* Relation with 2 link keys
*/
public function userLanguagePivots(): HasManyThrough
{
return $this->newHasManyThrough(
($r = (new UserLanguagePivot()))->newQuery(),
$this, // Role
($t = (new UserRolePivot()))->setTable($t->getTable() . ' as t'),
't.role_id', // 2 UserRolePivot
'user_id', // 4 UserLanguagePivot
'id', // 1 Role
't.user_id' // 3 UserRolePivot
)->whereRaw($t->getConnection()->getTablePrefix() . 't.language = ' .
$r->getConnection()->getTablePrefix() . $r->getTable() . '.language');
}Notice how the language condition/column is NOT in the current model but in the through table.
The relation defined in UserLanguagePivot to Role model would look like this:
/**
* Relation with 2 link keys
*/
public function roles(): HasManyThrough2LinkTables
{
return (new HasManyThrough2LinkTables(
$this->newRelatedInstance(Role::class)->newQuery(),
$this, // UserLanguagePivot
($f = (new self()))->setTable($f->getTable() . ' as f'),
'f.id', // 2 self UserLanguagePivot
'id', // 6 Role
'id', // 1 UserLanguagePivot
'f.user_id', // 3 self UserLanguagePivot
($s = (new UserRolePivot()))->setTable($s->getTable() . ' as s'),
's.user_id', // 4 UserRolePivot
's.role_id', // 5 UserRolePivot
$this // UserLanguagePivot - needed for https://github.com/laravel/framework/issues/51825
))->whereColumn('f.language', '=', 's.language');
}Notice how the language condition/column is in the current model, thus making the through self mandatory (to avoid sql errors).