在资源索引上显示嵌套关系变量

Display nested relation variable on resource index

我正在使用 Laravel Nova 开发一个 Laravel 管理员。 我有数据库结构:

works
   id
   device_id
   work_type

devices
   id
   serial_number
   device_type_id

device_types
   id
   device_name
   brand_id

brands
   id
   brand

这是工作模式class

class Work extends Model {

    public function device() 
    {
        return $this->belongsTo( device::class );
    }

}

这是设备型号class

class Device extends Model {

    public function deviceType() 
    {
        return $this->belongsTo( DeviceType::class, 'device_type_id' );
    }

}

这是 DeviceType 型号 class

class DeviceType extends Model
{
    public function brand()
    {
        return $this->belongsTo( Brand::class );
    }

}

这是我的实际 Nova 资源


class Work extends Resource
{
    
    public function fields(Request $request)
    {
        return [
                BelongsTo::make( 'Serial number', 'device', 'App\Nova\Device' )->searchable()
         ];
    }
}

在 Laravel Nova“Works”索引页上,我想要这样的内容: |工号 |序列号 |设备类型 |品牌 | | ------ | -------------- | ---------- | ------ | |第 1234 章12345678901234 | S20 |三星| | 2345 | 99999999999999 | S21 |三星 |

我不知道如何显示“设备类型”和“品牌”列。

这些列也应该是可排序的。

要在 Works 索引页上将 device_typebrand 显示为列非常简单。只需将 device_typebrand 作为自定义属性添加到您的 Works 模型中。之后,您可以在您的 Nova 资源中访问它们。

工作模式

class Work extends Model {

    public function device() 
    {
        return $this->belongsTo( device::class );
    }

    public function getBrandAttribute(): string
    {
        return $this->device->deviceType->brand->brand ?? '';
    }

    public function getDeviceTypeAttribute(): string
    {
        return $this->device->deviceType->device_name ?? '';
    }

}

工作新星资源

class Work extends Resource
{
    
    // Override indexQuery to your liking, joining tables
    public static function indexQuery(NovaRequest $request, $query)
    {
        return $query->join('devices', 'devices.id',  '=','works.device_id')
            ->join('device_types', 'device_types.id', '=', 'device_type_id')
            ->join('brands', 'brands.id', '=', 'brand_id')
            ->select([
                'works.*', 
                'devices.device_type_id as device_type_id', 
                'devices_types.device_name as device_name', 
                'devices_types.brand_id as brand_id', 
                'brands.brand as brand'
            ]);
    }

    public function fields(Request $request)
    {
        return [
            BelongsTo::make( 'Serial number', 'device', 'App\Nova\Device' )
                ->searchable(),

            Text::make('Device name', 'device_name')
                ->onlyOnIndex()
                ->sortable(),

            Text::make('Brand', 'brand')
                ->onlyOnIndex()
                ->sortable(),
         ];
    }
}

不幸的是,Laravel Nova 无法对这些自定义属性进行开箱即用的排序,因为排序是在数据库级别完成的。

或者,您可以尝试将 indexQuery 函数更新为 described here。可能有添加此功能的软件包。

编辑

我在我自己的一个项目中对此进行了修改,它似乎确实可以通过覆盖 indexQuery 来工作。但是,我没有按照您的方式设置模型,因此我没有测试我的答案。我也不知道这在大规模上的表现如何。请参见上面的示例,让我知道它是否有效。顺便说一句,如果您决定覆盖 indexQuery 方法,您可以从模型中删除 custom attributes