根据关系获取标题 (laravel)

Get title based on relationship (laravel)

所以我有以下分类法:

一个学校hasMany个系。一个部门 hasMany class 是的。

一个系belongsTo一个学校。 AclassbelongsTo一个系一个学校

学校、系或 class 可以分配测试。这是通过数据透视表确定的,如下所示:

这一切都非常完美,但在测试页面上,我希望能够显示以下信息:

School Name | Department Name | Class Name

如果是 school-wide 那么它应该只显示学校名称。

如果它是 department-wide 那么它应该显示:School Name | Department Name

如果是 class 那么它应该显示:School Name | Department Name | Class Name.

我的 blade 代码如下所示:

{{$test->school->first()->name}}
        @if($test->department->isNotEmpty())
              |  
            {{$test->department->first()->name}}
        @if($test->class->isNotEmpty())
              |  
            {{$test->class->first()->name}}
        @endif
        @endif

这在 school-wide 测试时工作正常,但当我尝试为 class 加载测试时它会中断,因为它显然与部门通过数据透视表。相反,我需要做这样的事情:

{{$test->class->first()->department->school->name}}

这遍历了关系,但我如何将其巧妙地纳入我的视图以说明不同的场景?

欢迎大家帮忙!

通过考试 ID 获取学校:

School::whereHas('tests', function($q) use($testId) {
    $q->where('id', $testId);
})->first();

tests这里是多对多的关系。

获取部门和 class 的方式相同。

获取所有测试$tests = Test::all()(或根据需要添加查询范围)

使用 @foreach($tests as $test)

遍历每个测试

将关系添加到 Test 模型 class 学校、部门、Class

function school() {
    $this->belongsTo(School::class);
}

创建一个辅助函数来确定测试直接属于什么

function isFor($parent) {
    switch($parent) {
        case 'school':
            return $this->school;

        case 'department':
            return $this->department;

        case 'class':
            return $this->class;
    }
}

然后你可以在你的视图中使用它来检查测试直接属于什么

@if($test->isFor('school'))

如果您不想 switch/case 然后使用 if/elseif 做类似

function isFor() {
    if($this->school) {
        return 'school';
    }        
    elseif($this->department) {
        return 'department';
    }
    elseif($this->class) {
        return 'class';
    }
}

然后在视图中是这样的:

@if($test->isFor() == 'school')

一旦确定了直接父级是什么,您就可以直接从父级继续访问名称,而不必通过另一个关系,因此:

@if($test->isFor('department'))

{{ $test->department->name }}

我还建议为每个不同的视图创建不同的 partials/views

@if($test->isFor('department'))
    @include('partials.test-department')
@endif

并准确地把那个视图应该包含在那个部分