Reputation: 2071
I came accros a problem with laravel's ORM, eloquent and found no solution yet.
I have some tables as follows
Team
- id
- name
User
- id
- name
- role
- team_id
Student_Info
- id
- user_id
- data1
- data2
- etc ...
Project
- id
- student_id
- name
Now, I want to query all projects a certain team
, where team = 'some team'
Now the thing here is, without an ORM, it's simple, I would have done multiple joins in raw SQL.
However, because all these tables have a common column "name" I will have to alias all this stuff, which is really boring
With eloquent I can't find a way to do this query using "has many through" because it only allows on intermediate and I can't do a raw SQL as the alis thing is really a pain in the ass and as it would be very difficult to map the result to laravel's Models
Upvotes: 4
Views: 5295
Reputation: 25906
There is no native relationship for this case.
I created a HasManyThrough
relationship with unlimited levels: Repository on GitHub
After the installation, you can use it like this:
class Team extends Model {
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function projects() {
return $this->hasManyDeep(Project::class, [User::class, StudentInfo::class],
[null, null, 'student_id']);
}
}
$projects = Team::where('name', 'some team')->first()->projects;
Upvotes: 10
Reputation: 13259
Try with relationship existence. This assumes you have all relationships properly defined
$projects = Project::whereHas('students.user.team', function ($query) {
$query->where('name', '=', 'some team');
})->get();
That's 3 levels of nesting. Never tested. However, if you already define a Project-User relationship via hasManyThrough()
you can shorten it to 2 levels only.
$projects = Project::whereHas('user.team', function ($query) {
$query->where('name', '=', 'some team');
})->get();
Those will give you the data for projects only. If you also want the the intermediate data, use eager loading instead with with()
. Just replace whereHas()
by with()
.
$projects = Project::with('user.team', function ($query) {
$query->where('name', '=', 'some team');
})->get();
Upvotes: 1