I have problem with Laravel migrations. I want to make a relationship between two tables but
I am getting error General error: 1005 Can't create table
eshopper.prices (errno: 150 "Foreign key constraint is incorrectly
formed") (SQL: alter table prices add constraint pri ces_product_id_foreign foreign key (product_id) references
products (id) .
Here is my code. Tables are prices and products.
Prices
public function up()
{
Schema::create('prices', function (Blueprint $table) {
$table->id();
$table->float('amount');
$table->unsignedBigInteger('product_id')->unsigned()->index();
$table->foreign('product_id')->references('id')->on('products')->onUpdate('cascade')->onDelete('cascade');
$table->timestamps();
});
}
Products
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string("title",100);
$table->text("description");
$table->timestamps();
});
}
NOTE: In my migrations products table is under prices table, I know that the first created table is prices than products and that is error.
My question is do I have to put products frst or I can keep same layout(prices first, than products) and change something in code?
it happens because the product_id field type is different from the id field in the products table, try this in the products migration file:
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->unsignedBigInteger('id', true); // true here means it's auto incremental
$table->string("title",100);
$table->text("description");
$table->timestamps();
});
}
Instead of putting the constraints inside the migration file of price you can put it inside the migration file of products. Since it will create the prices table first before the products the constraints will not be created because the products table is not yet created.
/**
* This is the prices table
*
* it depends in you if you want to define the column here directly without its constraints
* the commented column is optional
*/
public function up()
{
Schema::create('prices', function (Blueprint $table) {
$table->id();
$table->float('amount');
//$table->unsignedBigInteger('product_id');
$table->timestamps();
});
}
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string("title",100);
$table->text("description");
$table->timestamps();
});
// you can define your constraints here
Schema::table('prices', function(Blueprint $table) {
$table->foreignId('product_id')
->constrained('products')
->cascadeOnDelete()
->cascadeOnUpdate();
// if you uncomment the column commented on the prices table instead of the one at above you can use this instead
$table->foreign('product_id')
->references('id')
->on('products')
->cascadeOnDelete()
->cascadeOnUpdate();
});
}
Short answer is that you MUST put products first before prices. If the whole code is still in development and have yet to get deployed, then the easiest solution is to rename the products table migration so that it has older timestamp than the prices migration has.
Related
I'm creating a table where I want to use the ID from this table "menu_items" to be added in another table
Table one: menu_items
Schema::create('menu_items', function (Blueprint $table) {
$table->id('menu_level_item_id');
$table->timestamps();
$table->string('menu_item_name');
$table->string('menu_item_desc');
Table 2 products
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('product_name');
$table->string('product_desc');
$table->integer('price');
$table->integer('menu_level_item_id');
$table->timestamps();
});
My aim of doing this is that I can then create a relationship between the 2 tables as they have the same key?
Is there a different approach I can take? Should I create a unique key when creating a menu item and then add this to the second table?
Thank you.
Basically Laravel Eloquent do the key handling. When you have two tables which both has as key the name id, this is not a problem. Name the keys in the relation table just like this
table1_id
table2_id
Laravel will handle this in Eloquent. You are also able to name the two columns in the relation table to what ever you want. You could define it for the relation in Eloquent. E.g.
public function otherModel () {
return $this->belongsToMany('App\Models\OtherModel', 'table_name', 'this_model_id', 'other_model_id');
}
Please have a look into:
Laravel Relationship Documentation
Schema::create('menu_items', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('menu_item_name');
$table->string('menu_item_desc');
table->timestamp();
});
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('product_name');
$table->string('product_desc');
$table->integer('price');
$table->unsignedBigInteger('menu_level_item_id');
$table->timestamps();
$table->foreign('menu_level_item_id')->references('id')->on('menu_items');
});
I'm try to create many-to-many that link with customer and shop in laravel but stuck in this error (errno: 150 "Foreign key constraint is incorrectly formed") and still, not figure it out.
Here my customers table
Schema::create('customers', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('shop_id');
$table->string('name');
$table->string('email');
$table->string('phone');
$table->timestamps();
$table->foreign('shop_id')->references('id')->on('shop');
});
Here my shops table
Schema::create('shops', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('customer_id');
$table->string('name');
$table->timestamps();
$table->foreign('customer_id')->references('id')->on('customer');
});
My Shop Model
protected $fillable = ['name'];
public function customer()
{
return $this->belongsToMany(\App\Customer::class);
}
My Customer Model
protected $fillable = ['name', 'email', 'phone'];
public function shop()
{
return $this->belongsToMany(\App\Shop::class);
}
Any Help? Thanks in advances....
Check your Schema -
Its should be shops not shop...
$table->foreign('shop_id')->references('id')->on('shops');
and similarly customers not customer...
$table->foreign('customer_id')->references('id')->on('customers');
Note for you. Don't use foreign command in table create command together.
Make sure always new migration file for adding foreign key's inside table.
Cause sometime its generate Errors while migrating ..
open your bash shell or PHP Storm Terminal or CMD
php artisan make:migration foreign_customer_id_at_table_shops --table=shops //you Can use your own migration name what you want
at foreign_customer_id_at_table_shops migration file
UP
$table->foreign('customer_id')->references('id')->on('customers');
DOWN
$table->dropForeign(['customer_id']);
Put the foreign key in relationship rather than in migration.
public function customer()
{
return $this->belongsToMany('\App\Customer::class','id','shop_id');
}
public function shop()
{
return $this->belongsToMany('\App\Shop::class','id','customer_id');
}
The relation of many-to-many need third table pivot table which you miss it.
for do that create new migration.
php artisan make:migration create_customer_shop
there is no need create model for pivot table
then you Schema pivot table something like this.
Pivot table
Schema::create('cutomer_shop', function (Blueprint $table) {
$table->increments('id');
$table->integer('customer_id')->unsigned();
$table->integer('shop_id')->unsigned();
$table->timestamps();
$table->foreign('customer_id')->references('id')->on('customers');
$table->foreign('shop_id')->references('id')->on('shops');
});
The two table shops and customers doesn't have any direct relations they have relation by just pivot table.
Note: make sure all three table id type increments('id') and all foreign key are $table->integer('shop_id')->unsigned(); otherwise give you incorrect format error.
I'm creating a foreign key relationship between the orders and order_status tables. When I get a new order from the customer and ship that order, I set that order status to shipped when the order is received to that customer. I set shipped and received status, and then that order will start showing on the orders history page. Am I doing this correctly?
class CreateOrdersTable extends Migration
{
public function up()
{
Schema::create('orders', function (Blueprint $table) {
$table->bigIncrements('id');
$table->text('customer_name');
$table->string('customer_email');
$table->string('customer_contact');
$table->bigInteger('order_status_id')->unsigned();
$table->string('product_names');
$table->string('products_quantity');
$table->text('customer_address');
$table->timestamps();
});
}
Here's the order_status table:
class CreateOrderStatusTable extends Migration
{
public function up()
{
Schema::create('order_status', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('status')->nullable();
$table->timestamps();
});
}
}
From the looks of it, an Order could have multiple OrderStatuses. To facilitate this in Eloquent (not covered here), your order_status table needs another column referencing theorders table.
Add this to the order_status migration:
$table->bigInteger('order_id')->unsigned()->index();
$table->foreign('order_id')->references('id')->on('orders');
I have two tables rta_list and rta_reg_company. I have a column count in rta_list table.
Schema::create('rta_list', function (Blueprint $table) {
$table->increments('rta_id');
$table->string('rta_name');
$table->string('rta_address');
$table->string('rta_phone');
$table->string('rta_email')->unique();
$table->integer('count');
$table->timestamps();
});
Schema::create('rta_reg_company', function (Blueprint $table) {
$table->increments('company_id');
$table->integer('rta_id')->unsigned();
$table->foreign('rta_id')
->references('id')
->on('rta_lists')
->onDelete('cascade');
$table->string('company_name');
$table->string('company_isin');
$table->string('company_script');
$table->string('company_address');
$table->string('company_phone');
$table->string('company_email');
$table->timestamps();
});
I want to increase the value of count of rta_list table by rta_id when I add new RTA Registered Company. For eg: if i add one company then, The value must be added in rta_reg_company table and count must be 1 in count column in rta_list table.
Also also how to show the count value by rta_id in view..
Help Needed.....
you can use laravel Observer to raise an event on a model creation.then you can update as below on model Observer:
public function created(Company $company)
{
DB::table('rta_list')->increment('count');
}
The many to many relationship works. The original working migration:
Schema::table('tag_topic', function (Blueprint $table) {
$table->integer('topic_id')->unsigned()->index();
$table->integer('tag_id')->unsigned()->index();
});
I want the pivot table items to be deleted when referenced items are deleted. The new migration:
Schema::table('tag_topic', function (Blueprint $table) {
$table->foreign('topic_id')->references('id')->on('topics') ->onDelete('cascade');
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
});
The pivot table row items are not cascaded deleted.
Update:
I dropped the table and rewrote the the migration, but still the pivot rows are not cascade deleted:
Schema::create('tag_topic', function (Blueprint $table) {
$table->integer('topic_id')->unsigned();
$table->integer('tag_id')->unsigned();
$table->foreign('topic_id')->references('id')->on('topics')->onDelete('cascade');
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
});
This code deletes the pivot table rows:
$tag = Tag::where('id', $tag->id)->get()->first();
$Tag->topics()->detach();
Try dropping your old indexes before applying the foreign key constraints.
Schema::table('tag_topic', function (Blueprint $table) {
$table->dropIndex(['topic_id']);
$table->dropIndex(['tag_id']);
$table->foreign('topic_id')->references('id')->on('topics')->onDelete('cascade');
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
});