【问题标题】:Display nested relation variable on resource index在资源索引上显示嵌套关系变量
【发布时间】:2021-07-14 13:53:17
【问题描述】:

我正在使用 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 Work extends Model {

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

}

这是设备模型类

class Device extends Model {

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

}

这是 DeviceType 模型类

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 |三星 |

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

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

【问题讨论】:

    标签: laravel laravel-nova


    【解决方案1】:

    device_typebrand 显示为Works 索引页上的列是相当简单的。只需将 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

    【讨论】:

    • 非常感谢!它就像一个小小的调整的魅力:)
    • 我只改变了这个:->select( 'works.*', 'devices.device_type_id as device_type_id', 'device_types.device_name as device_name', 'device_types.brand_id as brand_id', 'brands.brand as brand' )
    • 太棒了!我会相应地更新答案。当然,您需要所有工作领域。这表现如何?分页仍然按预期工作吗?我想应该是,但我很好奇!
    • 似乎一切正常!分页、自定义过滤器(按设备类型、设备名称)和导出到 Excel(使用外部包)可以正常工作。再次感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 2019-12-17
    相关资源
    最近更新 更多