【问题标题】:How to have a page display all relationships in Nova如何让页面显示 Nova 中的所有关系
【发布时间】:2025-12-22 18:35:12
【问题描述】:

如何让一个资源视图在查看所有资源页面中显示所有关系的数据(并且希望仍然可以排序和搜索)?

例如,我有 2 个表:

供应商 - id、供应商名称 产品 - id、product_name、年份

我想要一个视图来显示表格:

供应商 ID |供应商名称 |产品编号 |产品名称 |年份

目前,我有一个供应商页面和一个产品页面。我想将结果合二为一。

【问题讨论】:

    标签: laravel laravel-nova


    【解决方案1】:

    针对你的表结构和你的需求,我推荐这个解决方案:

    // database\migrations\2019_10_04_153155_create_vendors_table.php
            Schema::create('vendors', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('name',100);
                $table->timestamps();
            });
    // database\migrations\2019_10_04_153325_create_products_table.php
            Schema::create('products', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('name',100);
                $table->integer('year');
                $table->timestamps();
            });
    // database\migrations\2019_10_04_154713_create_product_vendor_table.php
            Schema::create('product_vendor', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->bigInteger('product_id');
                $table->bigInteger('vendor_id');
                $table->timestamps();
            });
    // app\Product.php
    class Product extends Model
    {
        public function vendors()
        {
            return $this->belongsToMany(Vendor::class,'product_vendor');
        }
    }
    // app\Vendor.php
    class Vendor extends Model
    {
        public function products()
        {
            return $this->belongsToMany(Product::class,'product_vendor');
        }
    }
    // app\ProductVendor.php
    <?php
    namespace App;
    use Illuminate\Database\Eloquent\Model;
    use \App\Product;
    use \App\Vendor;
    class ProductVendor extends Model
    {
        protected $table = 'product_vendor';
        public function GetColumnProductNameAttribute()
        {
            if($this->product_id){
                return Product::find($this->product_id)->name;
            }else{
                return '';
            }
        }
        public function GetColumnVendorNameAttribute()
        {
            if($this->vendor_id){
                return Vendor::find($this->vendor_id)->name;
            }else{
                return '';
            }
        }
        public function GetColumnProductYearAttribute()
        {
            if($this->product_id){
                return Product::find($this->product_id)->year;
            }else{
                return '';
            }
        }
    }
    // app\Nova\Product.php
        public static $title = 'name';
    // app\Nova\Vendor.php
        public static $title = 'name';
    // app\Nova\ProductVendor.php
    <?php
    namespace App\Nova;
    use Laravel\Nova\Fields\ID;
    use Laravel\Nova\Fields\Text;
    use Laravel\Nova\Fields\Number;
    use Illuminate\Http\Request;
    use Laravel\Nova\Http\Requests\NovaRequest;
    class ProductVendor extends Resource
    {
        public static $model = 'App\ProductVendor';
        public static $title = 'id';
        public static function indexQuery(NovaRequest $request, $query)
        {
            return $query->join('vendors', 'product_vendor.vendor_id', '=', 'vendors.id')
            ->join('products', 'product_vendor.product_id', '=', 'products.id')
            ->select('vendors.name as column_vendor_name','products.name as column_product_name','products.year as column_product_year','product_vendor.*','products.*','vendors.*');
        }
        public static $search = [
            'id','products.name','vendors.name'
        ];
        public function fields(Request $request)
        {
            return [
                ID::make()->sortable(),
                ID::make('Vendor Id','vendor_id')
                    ->sortable(),
                Text::make('Vendor Name','column_vendor_name')
                    ->sortable()
                    ->hideWhenCreating(),
                ID::make('Product Id','product_id')
                    ->sortable(),
                Text::make('Product Name','column_product_name')
                    ->sortable()
                    ->hideWhenCreating(),
                Text::make('Product Year','column_product_year')
                    ->sortable()
    
            ];
        }
        public function cards(Request $request)
        {
            return [];
        }
        public function filters(Request $request)
        {
            return [];
        }
        public function lenses(Request $request)
        {
            return [];
        }
        public function actions(Request $request)
        {
            return [];
        }
    }
    

    主要思想是显示数据透视表 product_vendor 与 2 个表连接:产品和供应商。然后通过一些基本的命令设置,您将能够搜索产品名称、供应商名称(或更多)和可排序(全部)。祝你好运,如果你需要,问我!

    更新:

    为了修复可排序和搜索 id 的错误,需要在 ProductVendor Nova 中进行一些更改:

    // indexQuery:
        public static function indexQuery(NovaRequest $request, $query)
        {
            return $query->join('vendors', 'product_vendor.vendor_id', '=', 'vendors.id')
            ->join('products', 'product_vendor.product_id', '=', 'products.id')
            ->select('product_vendor.id as temp_id','products.id as temp_product_id','vendors.id as temp_vendor_id','vendors.name as column_vendor_name','products.name as column_product_name','products.year as column_product_year','product_vendor.*','products.*','vendors.*');
        }
    // $search
        public static $search = [
            'product_vendor.id','products.name','vendors.name'
        ];
    // fields function
        public function fields(Request $request)
        {
            return [
                ID::make('ID','temp_id')->sortable(),
                ID::make('Vendor Id','vendor_id')
                    ->sortable(),
                Text::make('Vendor Name','column_vendor_name')
                    ->sortable()
                    ->hideWhenCreating(),
                ID::make('Product Id','product_id')
                    ->sortable(),
                Text::make('Product Name','column_product_name')
                    ->sortable()
                    ->hideWhenCreating(),
                Text::make('Product Year','column_product_year')
                    ->sortable()
    
            ];
        }
    

    【讨论】:

    • 谢谢。我实际上搬离了 Nova,但这会奏效。