'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 |