I have 3 tables: Roles, Teams, Users with a pivot table between each: role_team, role_user, team_user.
I'm having a hard time leveraging Eloquent to return only the roles that a user has for a specific team.
$team = Team::find(1);
foreach($team->users as $user) {
dump($user->teamRoles); // Get the roles this user has for the team
}
While I could do $user->roles()->where('team_id', $team->id)->get()
, I'd like to specify it as a relationship. I tried setting up a hasManyThrough
, but it doesn't seem to work in this specific case.
The need to use this as a relationship rather than query is because I'm using Lighthouse PHP for GraphQL and would like to easily be able to query for the roles like:
teams {
id name
users {
teamPivot {
roles { id name }
}
}
}
Any help leveraging Eloquent to make this happen would be greatly appreciated.
One possible solution, though not necessarily the one I'm looking for is to use the @method
directive on a field.
Imagine the following schema:
type User {
id: ID!
email: String!
teams: [Team] @belongsToMany
teamMeta: TeamUser
}
type Team {
id: ID!
name: String!
users: [User] @belongsToMany
userMeta: TeamUser
}
type Role {
id: ID!
name: String!
team: Team @belongsTo
users: [User] @belongsToMany
}
type TeamUser {
user: User!
team: Team!
roles: [Role] @method(name: "getTeamRoles")
}
Where getTeamRoles
looks like:
public function getTeamRoles()
{
return $this->user->roles()->where('team_id', $this->team->id)->get();
}
This configuration will allow the following GraphQL to work as desired:
users(first: 1, input: { id: 2 }) {
email teams {
name userMeta {
contactedAt
roles { id name }
}
}
}
This is currently the solution I'm running, but it would be nice to have a "pure" Eloquent answer for this instead of having to write a custom accessor for each relation of this type.