I have a multi-tenant setup where a tenant HasMany
workspaces and a workspace BelongsToMany
students. How do I create a relationship from the tenant where I retrieve all the students from all workspaces within the tenant?
I've took a look at hasManyThrough
but that does not solve the problem. Right now I have this function:
public function getStudents()
{
$this->workspaces()->get()->map(function ($workspace) {
return $workspace->students;
})->flatten()->unique();
}
But I'd like to do it in a relation instead of the above code. Any advice?
Tenant :HasMany=> Workspace(tenant_id) :BelongsToMany=> Student(student_workspace table)
Thanks in advance!
CodePudding user response:
You could do it through join
like:
public function students(){
return Student::select('students.*')
->join('student_workspace', 'students.id', '=', 'student_workspace.student_id')
->join('workspaces', 'workspaces.id', '=', 'student_workspace.workspace_id')
->join('tenants', 'tenants.id', '=', 'workspaces.tenant_id')
->where('tenants.id', $this->id);
}
Or like any normal relation using this package: hasManyDeep through the following steps:
First:
composer require staudenmeir/eloquent-has-many-deep
In your Workspace
model file:
public function students()
{
return $this->belongsToMany(Student::class, 'student_workspace');
}
In your Tenant
model file:
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
class Tenant extends Model
{
use HasFactory, HasRelationships;
public function students(){
return $this->hasManyDeepFromRelations($this->workspaces(), (new Workspace)->students());
}
}
Hope this would be helpful.