'Laravel relationship belongsToMany with composite primary keys

I have 3 tables and I'm trying to make relations between order_products and order_products_status_names. I have transition/pivot table named order_product_statuses. The problem are my PK, becuase I have in table orders 3 Pk, and I don't know how to connect this 3 tables throught relationships. My migrations are:

Table Order Products:

 public function up()
{
    Schema::create('order_products', function (Blueprint $table) {
        $table->integer('order_id')->unsigned();
        $table->integer('product_id')->unsigned();
        $table->integer('ordinal')->unsigned();
        $table->integer('size');

        $table->primary(['order_id', 'product_id', 'ordinal']);
        $table->foreign('order_id')->references('id')->on('orders');
        $table->foreign('product_id')->references('id')->on('products');
    });
}

Table Order Product Statuses - this is my transition/pivot table between order_products and order_product_status_names

 public function up()
{
    Schema::create('order_product_statuses', function (Blueprint $table) {
        $table->integer('order_id')->unsigned();
        $table->integer('product_id')->unsigned();
        $table->integer('status_id')->unsigned();
        $table->integer('ordinal')->unsigned();
        $table->dateTime('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));

        $table->foreign('order_id')->references('id')->on('orders');
        $table->foreign('status_id')->references('id')->on('order_product_status_names');
        $table->primary(['order_id', 'product_id', 'ordinal']);
    });
}

And the last one is Order Product Status Names

public function up()
{
    Schema::create('order_product_status_names', function (Blueprint $table) {
        $table->integer('id')->unsigned();
        $table->string('name');
        $table->string('code');
        $table->dateTime('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));

        $table->primary('id');
    });
}

I know that here is relationship blengsToMany in two ways, but I don't know or can I declarate this relation ( from order_products to order_product_status_names and inverse )?



Solution 1:[1]

Ok haven't spent a great amount of time on this, but this is kind of what I would do. Also as @Devon mentioned I would probably add ids to each table seeing as Eloquent isn't really designed for composite keys. As mentioned in one of my comments I usually create startup and update scripts, so the syntax might not be exactly right:

public function up() {
    Schema::create('order_products', function (Blueprint $table) {
        $table->bigIncrements('id')->unsigned();
        $table->integer('order_id')->unsigned();
        $table->integer('product_id')->unsigned();
        $table->integer('order_product_statuses_id')->unsigned();
        $table->integer('ordinal')->unsigned();
        $table->integer('size');

        $table->primary('id');
        $table->foreign('order_id')->references('id')->on('orders');
        $table->foreign('product_id')->references('id')->on('products');
        $table->foreign('order_product_statuses_id')->references('id')->on('order_product_statuses');
    });
}

public function up() {
    Schema::create('order_product_statuses', function (Blueprint $table) {
        $table->bigIncrements('id')->unsigned();
        $table->integer('product_id')->unsigned();
        $table->integer('status_id')->unsigned();
        $table->integer('ordinal')->unsigned();
        $table->dateTime('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));

        $table->primary('id');
        $table->foreign('status_id')->references('id')->on('order_product_status_names');
    });
}

public function up() {
    Schema::create('order_product_status_names', function (Blueprint $table) {
        $table->bigIncrements('id')->unsigned();
        $table->string('name');
        $table->string('code');
        $table->dateTime('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));

        $table->primary('id');
    });
}

I hope that helps you out a bit.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Zymotik