Schema::create('menus', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->string('slug')->unique();
$table->integer('price');
$table->text('description');
$table->timestamps();
});
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->string('slug')->unique();
$table->timestamps();
});
Schema::create('category_menu', function (Blueprint $table) {
$table->increments('id');
$table->integer('menu_id')->unsigned()->nullable();
$table->foreign('menu_id')->references('id')
->on('menus')->onDelete('cascade');
$table->integer('category_id')->unsigned()->nullable();
$table->foreign('category_id')->references('id')
->on('categories')->onDelete('cascade');
$table->timestamps();
});
When I run php artisan:migrate, I get the following error.
SQLSTATE[HY000]: General error: 1005 Can't create table `mieaceh`.`category_menu` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `category_menu` add constraint `category_menu_menu_id_foreign` foreign key (`menu_id`) references `menus` (`id`) on delete cascade)
This is due to mismatch of datatype of foreign key column and the referenced column most likely
When you create a primary key with $table->id() the datatype of the auto incrementing id column is unsignedBigInteger so you must have foreign key also with the same datatype
Schema::create('category_menu', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('menu_id');
$table->foreign('menu_id')->references('id')
->on('menus')->onDelete('cascade');
$table->unsignedBigInteger('category_id');
$table->foreign('category_id')->references('id')
->on('categories')->onDelete('cascade');
$table->timestamps();
});
You shouldn't make the columns in a pivot table nullable for the foreign keys to maintain data integrity.
Also be consistent with the datatype for primary key columns as well as definitions - when using $table->id() keep that consistent across all migrations for all tables. That way you will have less chances of mismatch when defining foreign keys as $table->unsignedBigInteger()
laravel migrations files contains a datetime slug that determine which file will be migrated first
notice the order
2021_10_11_101533_create_posts_table.php
2014_10_12_000000_create_users_table.php
when you run
php artisan migrate
posts table will be migrated first and it contains a foriegn key
user_id
which references a primary key on users table
id
but the users table doesn't exists yet, to fix this issues change the files names and make sure users table migrate first like this
notice the order
2014_10_10_000000_create_users_table.php
2021_10_11_101533_create_posts_table.php
short pattern for declaring a foreign key
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
Related
Try to create foreign key in Laravel 7 but when I migrate tables using artisan it gives error
SQLSTATE[HY000]: General error: 3780 Referencing column 'remote_id' and referenced column 'parent_id' in foreign key constraint 'products_remote_id_foreign' are incompatible. (SQL: alter table products add constraint products_remote_id_foreign foreign key (remote_id) references categories (parent_id) on delete cascade)
My categories table
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('parent_id');
$table->tinyInteger('depth');
$table->string('name');
$table->string('slug');
$table->text('description');
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->default(DB::raw('NULL ON UPDATE CURRENT_TIMESTAMP'))->nullable();
});
My products table
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('remote_id');
$table->foreign('remote_id')->references('parent_id')->on('categories')->onDelete('cascade');
$table->unsignedBigInteger('category_id');
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
$table->string('name');
$table->text('description');
$table->integer('price');
$table->tinyInteger('status')->default(1);
$table->integer('qty');
$table->string('barcode')->nullable();
$table->string('image');
$table->text('images')->nullable();
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->default(DB::raw('NULL ON UPDATE CURRENT_TIMESTAMP'))->nullable();
});
Any ideas as to what I've done wrong?
Thanks for help!!!
As mentioned by aynber, for foreign keys to be compatible, they must be of the same type. Your remote_id in your products table is an unsignedBigInteger while the key you are trying to reference in your categories table, parent_id, is an integer. To fix this either change category_id in your products table to an integer or change parent_id in your categories table to an unsignedBigInteger.
Edit:
I looked a little more into foreign keys and found this useful answer on another post. Foreign keys need to have a unique constraint or be a primary key. Since your remote_id column is referencing parent_id which is neither a primary key nor has a unique constraint, you are getting this error.
The solution given in the other question for adding a unique constraint is running this command(modified for your tables):
alter table categories add constraint uq1 unique (parent_id);
Using Laravel 5.3 and Eloquent model, Trying to make a user role model.
the main schema that I have 2 tables users and roles, each user have a role and every role have many users (one to many relationship).
when i'm trying to make a foreign key in user table that references the id in roles table it gives me this error
In Connection.php line 647:
SQLSTATE[HY000]: General error: 1005 Can't create table
mydata.#sql-7e0_71 (errno: 150 "Foreign key constraint is incorrectly
formed") (SQL: alter table "user" add constraint
"user_role_id_foreign" foreign key ("role_id") references roles("id"))
In Connection.php line 449:
SQLSTATE[HY000]: General error: 1005 Can't create table
mydata.#sql-7e0_71 (errno: 150 " Foreign key constraint is
incorrectly formed")
Note: I'm using artisan command migrate, and I've tried these answers 1,2
here is my up() function for my user migration
public function up()
{
Schema::create('user', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->integer('role_id')->unsigned();
$table->string('remember_token')->nullable();
$table->timestamps();
$table->foreign('role_id')->references('id')->on('role');
});
}
and for role table
public function up()
{
Schema::create('role', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('description');
$table->timestamps();
});
}
You are trying to add a foreign key that have a reference on the roles table (->on('roles')), but in your migration file you are creating a table named role (Schema::create('role', ...).
You need to match those.
Either changed the name of the role table to roles or your reference to the role table.
I have started a new Laravel 5.5 project and I am receiving the following error when trying to add a foreign key to my users table:
General error: 1215 Cannot add foreign key constraint (SQL: alter table users add constraint users_organization_id_foreign foreign key (organization_id) references organizations (id) on delete cascade)
Here is the migration code for the organization table:
Schema::create('organizations', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('subdomain')->nullable();
$table->timestamps();
$table->softDeletes();
});
Here is the migration code for the users table:
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->integer('organization_id')->unsigned();
$table->foreign('organization_id')->references('id')->on('organizations');
$table->string('first_name');
$table->string('last_name');
$table->string('email')->unique();
$table->timestamps();
$table->softDeletes();
});
I have researched this error online and the common thing to make sure of are that the data types are the same. From what I can see, they are the same. What's even crazier is that if I run this query in the database directly it works:
alter table `users` add constraint `users_organization_id_foreign` foreign key (`organization_id`) references `organizations` (`id`)
By default, in each Laravel fresh installation users table is created first. But since you're adding a constraint in this table, you need to create organizations table first.
So, put organizations table migration before users table migration by changing organizations migration date in the file name:
2014_01_01_000000_create_organizations_table.php
Going along with Alexey's answer. I would also suggest that you enable/disable foreign key constraints before you run your migrations:
Schema::disableForeignKeyConstraints();
// Your migration code.
Schema::enableForeignKeyConstraints();
This way you don't need to rename your migration files.
I try to migrate my tables but it display an error which is:
errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter
table users add constraint users_role_id_foreign foreign key
(role_id) references roles (id))
This is my tables:
Schema::create('users', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->string('fullname');
$table->string('username')->unique();
$table->string('email')->unique();
$table->string('password');
$table->integer('role_id')->unsigned();
$table->foreign('role_id')->references('id')->on('roles');
$table->rememberToken();
$table->timestamps();
});
Schema::create('roles', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->string('name')->unique();
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
Schema::create('posts', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->string('content');
$table->string('image');
$table->timestamps();
});
The problem is that when you create the users table with a foreign key to the roles table, then the roles table does not exist yet, therefore you cannot add a foreign key referencing it.
I also noted that the roles table also has a foreign key referencing the users table, which makes the situation more tricky.
If you are absolutely sure that the roles table needs a foreign key to the users table, then you need to remove the foreign key creation from the users table definition, and add it separately back as alter table after the roles table is created.
However, I'm not sure that the roles table should have an fk to the users table (unless it represents the user that created the role) because you can have multiple users in a role. If you are modelling a many-to-many relationship, then this is not the way to do it. But this has got nothing to do with the current error, so treat this as a side note only.
Sometimes that error can also occur due to migrations order. If you face errno 150 "Foreign key constraint is incorrectly formed" then go to your migrations folder and check whether the parent table migration was executed first or not. If child table migration is executed first according to the migration order, it will try to find foreign key binding and shows that error.
I'm trying to get price value from products table and set it to sold table. Can u please tell me why I'm getting this error ? product_id and user_id works fine. But I get error when I need to create foreign price in sold table
SOLD table
Schema::create('sold', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->integer('product_id')->unsigned();
$table->foreign('product_id')->references('id')->on('products');
$table->integer('price')->unsigned();
$table->foreign('price')->references('price')->on('products');
$table->integer('bid_price')->unsigned();
$table->foreign('bid_price')->references('bid_price')->on('products');
$table->timestamps();
});
PRODUCTS table
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->string('slug');
$table->string('title');
$table->text('body');
$table->integer('price');
$table->integer('bid_price');
$table->string('address');
$table->string('condition');
$table->integer('quantity');
$table->string('img_1');
$table->string('img_2');
$table->string('img_3');
$table->string('img_4');
$table->integer('views');
$table->timestamps();
});
Error message:
General error: 1215 Cannot add foreign key constraint (SQL
: alter table `sold` add constraint sold_price_foreign foreign key (`price`
) references `products` (`price`))
EDIT
`LATEST FOREIGN KEY ERROR
------------------------
2016-03-01 12:40:08 31a0 Error in foreign key constraint of table auction/#sql-2564_ef:
foreign key (`price`) references `products` (`price`):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html
for correct foreign key definition.`
Cannot find an index in the referenced table
Your products table needs an INDEX on the column you are trying to reference. I'd say this has to be unique otherwise MySQL is unable to determine which row it is referencing.
Check this link: MySQL Cannot Add Foreign Key Constraint
The second answer there says:
I had set one field as "Unsigned" and other one not. Once I set both columns to Unsigned it worked.
So I would assume making the column "price" on your products unsigned too, should solve the problem.
Like this:
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->string('slug');
$table->string('title');
$table->text('body');
$table->integer('price')->unsigned(); // <-- the difference is here!
$table->integer('bid_price');
$table->string('address');
$table->string('condition');
$table->integer('quantity');
$table->string('img_1');
$table->string('img_2');
$table->string('img_3');
$table->string('img_4');
$table->integer('views');
$table->timestamps();
});
Update:
The "LAST FOREIGN KEY ERROR" section tells you:
Cannot find an index in the referenced table
And the MySQL documentation says about foreign keys:
MySQL requires indexes on foreign keys and referenced keys
So basically you have to add an index to the price column in the products table.
I never worked with Laravel, but according to their documentation it should work like this:
$table->index('price');
Update 2:
I only considered the technical aspect here, but looking at the database structure in a semantical way, it is probably a bad idea to create a foreign key over price columns, because a price is not really an identifier for a product (products having the same price do exist!).