使用3向数据透视表中的嵌套模型进行Laravel范围查询

时间:2016-08-01 09:50:17

标签: php mysql json laravel model

我的产品模型需要与处理相关联,描述 如何操作产品 位置,描述 可以操纵产品的位置。

换句话说,产品可以处理多个位置

“产品数据”应与嵌套处理返回到位置,这样,对于数据库中的每个位置,产品都可以与相关的处理相关联,方案类似于下面:

Products [
    product_attributes,
    Positions [
        position_attributes,
        Processings: [
            processing_attributes
        ]
    ]
]

因此,我使用以下代码创建了 3向数据透视表

Schema::create('product_position_processing', function (Blueprint $table) {

    // 3-way pivot
    $table->integer('product_id')->unsigned()->index();
    $table->foreign('product_id', 'ppp_aid_foreign')->references('id')->on('products')->onDelete('cascade');
    $table->integer('position_id')->unsigned()->index();
    $table->foreign('position_id', 'ppp_bid_foreign')->references('id')->on('positions')->onDelete('cascade');
    $table->integer('processing_id')->unsigned()->index();
    $table->foreign('processing_id', 'ppp_cid_foreign')->references('id')->on('processings')->onDelete('cascade');
    $table->primary(['product_id', 'position_id', 'processing_id'], 'index-base-combined');

    // these attributes define the minimum and maximum order amount based on the product + position + processing combination
    $table->integer('minimum_order_amount')->nullable();
    $table->integer('maximum_order_amount')->nullable();

    $table->timestamps();
});

然后,我以这种方式定义了3种不同模型之间的关系:

处理 型号

class Processing extends Model {
    use SoftDeletes;

    protected $dates = ['deleted_at'];
    protected $guarded = ['id', 'created_at', 'updated_at'];
    protected $casts = [
        'is_publicly_hidden' => 'boolean'
    ];
    protected $hidden = ['pivot'];

    public function products() {
        return $this -> belongsToMany ( Product::class, 'product_position_processing', 'processing_id', 'product_id' );
    }

    public function positions () {
        return $this -> belongsToMany ( Position::class, 'product_position_processing', 'processing_id', 'position_id' );
    }

    ...
    ...

}

职位 模型

class Position extends Model {
    use SoftDeletes;

    protected $dates = ['deleted_at'];
    protected $guarded = ['id', 'created_at', 'updated_at'];
    protected $hidden = ['pivot'];

    public function products() {
        return $this->belongsToMany ( Product::class, 'product_position_processing', 'position_id', 'product_id' );
    }

    public function processings ( ) {
        return $this -> belongsToMany ( Processing::class, 'product_position_processing', 'position_id', 'processing_id' );
    }

    ...
    ...
}

产品 型号

class Product extends Model implements SluggableInterface {
    use SoftDeletes;
    use SluggableTrait;

    protected $dates = ['deleted_at'];
    protected $guarded = ['id', 'created_at', 'updated_at'];
    protected $sluggable = [
        'build_from' => 'name',
        'save_to'    => 'slug',
        'include_trashed' => true
    ];

    ...
    ...

    public function processings() {
        return $this->belongsToMany(Processing::class, 'product_position_processing', 'product_id', 'processing_id');
    }

    public function positions() {
        return $this->belongsToMany(Position::class, 'product_position_processing', 'product_id', 'position_id');
    }

    ...
    ...

    public function scopeWithCompleteData ($query) {
        return $query->with([
            ...
            ...
            'positions' => function($query) {
                return $query->with(['processings' => function ( $query ) {
                    return $query->select('id', 'name')->groupBy('processing_id');
                }])->groupBy('position_id');
            },
            ...
            ...
        ]);
    }

}

现在,产品将通过 ProductsController 在json中返回,使用以下代码返回此格式的JSON。

产品获取者:

...
...
$products = Product::withCompleteData() -> get();
return $this -> ok ( $products );

示例“所有产品”@get JSON:

{
    "status": "OK",
    "data": [
        {
            "id": 1,
            "category_id": 1,
            "subcategory_id": 0,
            "brand_id": 1,
            "sku": "BD615149D6",
            ...
            ...
            "positions": [
                {
                    "id": 1,
                    "name": "POS1",
                    "processings": [
                        {
                            "id": 1,
                            "name": "PROC1",
                            "pivot": {
                                "position_id": 1,
                                "processing_id": 1
                            }
                        },
                        {
                            "id": 2,
                            "name": "PROC2",
                            "pivot": {
                                "position_id": 1,
                                "processing_id": 2
                            }
                        },
                        {
                            "id": 3,
                            "name": "PROC3",
                            "pivot": {
                                "position_id": 1,
                                "processing_id": 3
                            }
                        }
                    ]
                },
                {
                    "id": 2,
                    "name": "POS2",
                    "created_at": "2016-08-01 07:39:11",
                    "updated_at": null,
                    "deleted_at": null,
                    "processings": []
                },
                {
                    "id": 3,
                    "name": "POS3",
                    "created_at": "2016-08-01 07:39:11",
                    "updated_at": null,
                    "deleted_at": null,
                    "processings": []
                }
            ]
        },
        {
            "id": 2,
            "category_id": 2,
            "subcategory_id": 0,
            "brand_id": 2,
            "sku": "BD615149D6",
            ...
            ...
            "positions": [
                {
                    "id": 5,
                    "name": "POS5",
                    "created_at": "2016-08-01 07:39:11",
                    "updated_at": null,
                    "deleted_at": null,
                    "processings": []
                }
            ]
        }
    ]
}

问题是,返回的数据不正确。查询生成器似乎以一种奇怪的方式连接各种关系。不幸的是,我仍然没有足够主动地理解查询构建器的神奇之处,并且不知道如何调试以及在何处对代码进行修改。

任何人都可以帮助这个带有嵌套对象的3向数据透视表进入Laravel查询构建器吗?

0 个答案:

没有答案