Laravel 9 Migration not creating Foreign Key - php

I just have a fresh Laravel 9 (latest) installation. I have made some migrations successfully and tried to add foreign key constraints, but Laravel's not creating the actual Foreign Key itself. It doesn't throw any errors and I can query everything just fine, but no Foreign key is being created.
What's strange is that I've simply copied the Migration code from one of my older projects. Here is the 2 migration Schema:
Schema::create('users', function (Blueprint $table)
{
$table->id();
$table->string('name');
$table->timestamps();
});
Schema::create('posts', function (Blueprint $table)
{
$table->id();
$table->foreignId('user_id')->constrained();
$table->string('name');
$table->timestamps();
});
When I do the migration I get an index called posts_user_id_foreign but no Foreign Key is being added.
I have already tried the following variations on the Posts table with no success:
$table->foreignId('user_id')->constrained('users');
-----
$table->foreignId('user_id')->constrained('users')->onUpdate('cascade');
-----
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
Can anyone please tell me why is this happening and what's the solution? I had no issues creating Foreign Key before with Laravel. Not sure what's changed now in the latest version...

Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->nullable();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('name');
$table->timestamps();
});
you can use ondelete cascade or restrict

Related

laravel onDelete('cascade')

I have users table and session_requests table. When a user delete from user table, all session_requests related to him want to delete. I used laravel onDelete('cascade').
Schema::create('session_requests', function (Blueprint $table) {
$table->id();
$table->string('headline');
$table->string('objective');
$table->integer('status')->default(0);
$table->string('datetime');
$table->unsignedBigInteger('user_mentor_id');
$table->unsignedBigInteger('user_mentee_id');
$table->foreign('user_mentor_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('user_mentee_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
When I delete a user from users table, why don't delete data record in session_requests related to him. Could you please help me anyone? Thanks.

Laravel 9 adding foreign key constraint returns 150 error

I have created Roles table with Users table, I am trying to add foreign key to users table, but when I migrate, it returns 150 error.
I have googled a lot, I got a lot of answers, but no answer worked for me.
create_users_table Migration:
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->foreignId('role_id')
->constrained()
->onUpdate('cascade')
->onDelete('cascade');
$table->rememberToken();
$table->timestamps();
});
create_roles_table Migration:
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Can someone tell me what's wrong? I am stuck..
The problem is that roles table doesn't exist when you're creating a foreign key inside the users table.
So, your roles migration must be executed before you create a foreign key inside the users table.
There are 2 ways you can do this.
1- You either rename the roles and change the timestamp in name to be before the users migration. ( Not a good way though )
2- First create the tables and then create a new migration to insert the foreign key inside the users table.

SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint Error

I want to add role column on users table. But I got this error.
My Users migration
Schema::create('users', function (Blueprint $table) {
$table->increments("id");
$table->string('name');
$table->string("company_name")->unique();
$table->string('email')->unique();
$table->string("phone")->unique();
$table->boolean("status");
$table->integer("role")->unsigned();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
$table->foreign('role')->references('id')->on('roles')->cascadeOnUpdate()->cascadeOnDelete();
});
And my Role migration
Schema::create('roles', function (Blueprint $table) {
$table->increments("id");
$table->string('name');
});
The problem is occurring most probably from wrong migration order. As you are storing roles table id in your users table, you will have to migrate roles table first then your users table. As I don't know the order of your tables, I will assume from your post's order that the users table is being migrated first then the roles table, which is why users table is not being able to get the id reference of the roles table.
Try renaming the date of the roles table to a previous date than the users table and run php artisan cache:clear then php artisan migrate:fresh.
Just a couple of suggestion, as you have specified you are using Laravel 8, please use the id(); function instead of using increments("id");. To follow Laravel's foreign key rule please use role_id as the foreign key instead of role.
Instead of using: $table->foreign('role')->references('id')->on('roles')->cascadeOnUpdate()->cascadeOnDelete();
use:
$table->foreignId('role_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
You need to change your code as follows,
Schema::create('users', function (Blueprint $table) {
$table->increments("id");
$table->string('name');
$table->string("company_name")->unique();
$table->string('email')->unique();
$table->string("phone")->unique();
$table->boolean("status");
$table->unsignedBigInteger("role");
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
$table->foreign('role')->references('id')->on('roles')->cascadeOnUpdate()->cascadeOnDelete();
});
Based on the documentation here, you have used integer instead of unsignedBigInteger.
Try changing
$table->integer("role")->unsigned();
To
$table->foreignId('role_id');
$table->foreign('role_id')->references('id')->on('roles')
->onUpdate('cascade')->onDelete('cascade');
Make sure that role migrations has pre order in migrations before users migrations,
you can edit the migration name of roles migrations( edit timestamp to make it migrate before the users)

Foreign key constraint is incorrectly formed in Laravel

I am using Laravel 7 and PHP 7.4.
I'm working on databases and suddenly stuck over issue when I'm trying to generate a foreign key for user in another table. It should be straight away process and I'm following the doc, still getting error.
General error: 1005 Can't create table carchain_qrcode.sellers (errno: 150 "Foreign key constraint is incorrectly formed
User Table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigInteger('id');
$table->string('name')->unique();
$table->string('email')->unique();
});
}
Sellers Table
public function up()
{
Schema::create('sellers', function (Blueprint $table) {
$table->bigInteger('id');
$table->unsignedBigInteger('user_id');
$table->string('seller_name');
$table->string('seller_email');
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
});
Where have I gone wrong?
I think the problem is that the id of your users table is bigInteger and not bigIncrements or unsignedBigInteger.
In Laravel 7 you can simply do: $table->id() to create the id column.
Short: For quick fix refer to #Aless55 answer. The main thing to keep in mind is that id and foreign_key column types should match.
Correct way:
It is better to use Laravel's built-in APIs for creating primary key and foreign key. More details here:
It will automatically take care of column types, creating indexes, and so on. In addition, sticking to official documentation makes it easy to understand the code by others, and maintain it by the developer (It is just my opinion).
In your case:
Users table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->string('email')->unique();
});
}
Sellers table:
public function up()
{
Schema::create('sellers', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained(); // this will automatically detect which table to reference
$table->string('seller_name');
$table->string('seller_email');
});
}
this error occured due to incorrect data type used on the foreign key which you are going to create. The primary key data type on the users table should be same as the data type which you used in Sellers table as below:
Users Table
$table->id();
Sellers Table
$table->unsignedBigInteger('user_id');
or if you used any other data type on users table primary key then the foreign key in the other table should be same accordingly.

Add cascade/delete functionality to existing migration

I have 2 tables in my database. One for Courses and one for Course Chapters.
The migration for the courses looks like this:
Schema::create('courses', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
});
The migration for the chapters looks like this:
Schema::create('course_chapters', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedInteger('course_id');
$table->timestamps();
});
I want the course and the chapter to cascade down, so when i delete a course, the chapter also will be deleted.
Some examples i saw make use of deleting the foreign key but I never signed my column as a foreign key.
For example, normally, I could:
$table->dropForeign('course_id');
$table->foreign('course_id')
->references('id')->on('courses')
->onDelete('cascade');
How can i accomplish this in a (preferably) new migration and on what table should i add the foreign key?
This as it is should go on your course_chapters table:
$table->foreign('course_id')->references('id')->on('courses')->onDelete('cascade');
You don't need to add $table->dropForeign('course_id'); because that will drop the foreign key from the column.
NOTE: and this:
$table->unsignedInteger('course_id');
Should be this:
$table->unsignedBigInteger('course_id');
Because it will throw an error of using different data types.

Categories