So I have the following taxonomy:
A school hasMany
departments. A department hasMany
classes.
A department belongsTo
a school. A class belongsTo
a department and a school.
A school, department, or a class can have a test assigned to it. This is determined via pivot tables like so:
This all works absolutely perfectly, but on a test page, I want to be able to display the following info:
School Name | Department Name | Class Name
If it's school-wide then it should just show the school name.
If it's department-wide then it should show: School Name | Department Name
School Name | Department Name
.
And if it's for a class then it should show: School Name | Department Name | Class Name
School Name | Department Name | Class Name
School Name | Department Name | Class Name
.
My blade code looks like this:
{{$test->school->first()->name}}
@if($test->department->isNotEmpty())
|
{{$test->department->first()->name}}
@if($test->class->isNotEmpty())
|
{{$test->class->first()->name}}
@endif
@endif
This works fine for when it's a school-wide test but it will break when I'm trying to load up a test for a class as it obviously doesn't have a relationship to a department via the pivot tables. Instead I would need to do something like this:
{{$test->class->first()->department->school->name}}
That traverses the relationships, but how do I incorporate this neatly in my view to account for the different scenarios?
All help welcome!
Get all the tests $tests = Test::all()
(or add query scopes if needed)
Loop through each test using @foreach($tests as $test)
Add relationships to the Test
model class for School, Department, Class
function school() {
$this->belongsTo(School::class);
}
Create a helper function to determine what the Test directly belongs to
function isFor($parent) {
switch($parent) {
case 'school':
return $this->school;
case 'department':
return $this->department;
case 'class':
return $this->class;
}
}
Then you can use that in your view to check what the test directly belongs to
@if($test->isFor('school'))
If you don't want to switch/case
then use if/elseif
to do something like
function isFor() {
if($this->school) {
return 'school';
}
elseif($this->department) {
return 'department';
}
elseif($this->class) {
return 'class';
}
}
And then in the view something like:
@if($test->isFor() == 'school')
Once you determine what the direct parent is you can carry on accessing the names directly from the parent, instead of having to go through another relationship so:
@if($test->isFor('department'))
{{ $test->department->name }}
I'd also advise creating different partials/views for each different view
@if($test->isFor('department'))
@include('partials.test-department')
@endif
And put exactly what that view should contain in that partial
To get school by its test ID:
School::whereHas('tests', function($q) use($testId) {
$q->where('id', $testId);
})->first();
tests
here is many-to-many relationship.
The same way you can get department and class.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.