Cannot add foreign key constraint [Laravel 5.6] - mysql

tl;dr. Solution:
Thanks to Jonas.
the problem was that the tables I was referring as foreign, were not InnoDB.
I added raw SQL statements in alter migrations and then added the foreign keys:
DB::statement("ALTER TABLE table ENGINE='InnoDB';");
Original question
First, before the Stackoverflow police bust me, I know this question is probably 83% of the database of this website. But me is special (Kidding, I know I'm not). But I've tried most of the common stuff and nothing seems to work. So probably I'm overseeing something.
Error
General error: 1215 Cannot add foreign key constraint (SQL: alter table applications add constraint applications_user_id_foreign foreign key (user_id) references users (id) on delete cascade)
This is my migration:
public function up()
{
Schema::create("applications", function(Blueprint $table) {
$table->engine = "InnoDB";
$table->increments('id');
$table->timestamps();
});
Schema::table('applications', function($table) {
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('job_request_id')->unsigned()->index();
$table->foreign('job_request_id')->references('id')->on('job_requests')->onDelete('cascade');
$table->integer('status')->default(0);
});
}
What I've already tried:
1.
public function up()
{
Schema::create("applications", function(Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('job_request_id')->unsigned();
$table->foreign('job_request_id')->references('id')->on('job_requests')->onDelete('cascade');
$table->integer('status')->default(0);
});
}
2.
public function up()
{
Schema::create("applications", function(Blueprint $table) {
$table->engine = "InnoDB";
$table->increments('id');
$table->timestamps();
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('job_request_id')->unsigned();
$table->foreign('job_request_id')->references('id')->on('job_requests')->onDelete('cascade');
$table->integer('status')->default(0);
});
}
Splitting the migration into two files (A create and an alter). Even adding each reference one by one.
4.- using DB::statement('SET FOREIGN_KEY_CHECKS=0;'); and =1 at the beginning an the end og the migration.
5.- removing the unsigned() and the index().
Might mean something:
1.- When I rollback the migration, it doesn't delete the table. So if I rollback and migrate, would give me a "already exists error".
2.- I already have migrations which reference the same items, i.e:
Schema::create('job_requests', function (Blueprint $table) {
...
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users');
...
});
UPDATE
For the drop methods I've tried:
For the create migrations
public function down()
{
Schema::drop('applications');
}
public function down()
{
Schema::dropIfExists('applications');
}
2.- For the alter migrations
public function down()
{
Schema::table('applications', function (Blueprint $table) {
$table->dropForeign(['user_id']);
$table->dropColumn('user_id');
$table->dropForeign(['job_request_id']);
$table->dropColumn('job_request_id');
});
}
UPDATE 2:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('first_name');
$table->string('last_name')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
public function up()
{
Schema::create('job_requests', function (Blueprint $table) {
$table->increments('id');
$table->integer('status')->default(0);
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('job_requests');
}
I added three more alter migration:
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->engine = "InnoDB";
});
}
///////////////////////////
public function up()
{
Schema::table('job_requests', function (Blueprint $table) {
$table->engine = "InnoDB";
});
}
///////////////////////////
public function up()
{
Schema::table('applications', function (Blueprint $table) {
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('job_request_id')->references('id')->on('job_requests')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('applications', function (Blueprint $table) {
$table->dropForeign(['user_id']);
$table->dropForeign(['job_request_id']);
});
}
Without luck yet.

The referenced tables also have to use the InnoDB engine.
You can change them with raw SQL statements:
DB::statement("ALTER TABLE users ENGINE='InnoDB';");
DB::statement("ALTER TABLE job_requests ENGINE='InnoDB';");

for deleting the table:
public function down()
{
Schema::disableForeignKeyConstraints();
Schema::dropIfExists('applications');
}

Related

SQLSTATE[HY000]: General error: 1005 Can't create table `test`.`members` (errno: 150 "Foreign key constraint is incorrectly formed")

I'm using my migrations in Laravel to create the relationships between tables, and I have 4 tables: users, members, member_skills, and skills. I have the following code for the users table:
public function up()
{
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->rememberToken();
$table->timestamps();
$table->boolean('admin');
});
}
the members table:
public function up()
{
Schema::create('members', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('name');
$table->string('status');
$table->date('date')->nullable();
$table->text('project')->nullable();
$table->date('start')->nullable();
$table->foreign('name')->references('name')->on('users');
});
}
the member_skills table:
public function up()
{
Schema::create('member_skills', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('name');
$table->string('skill');
$table->foreign('name')->references('name')->on('members');
});
}
and the skills table:
public function up()
{
Schema::create('skills', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('skill');
$table->text('description');
$table->foreign('skill')->references('skill')->on('member_skills');
});
}
However, running my migrations results to (errno: 150 "Foreign key constraint is incorrectly formed"). I have read that changing the migration order should fix the problem, so I have arranged the 4 tables to be migrated in the order of users, members, member_skills, and skills, but I am still receiving the same error. Is there anything else I'm doing wrong?
Here is the right way todo this
public function up()
{
Schema::create('members', function (Blueprint $table) {
...
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
}
public function up()
{
Schema::create('member_skills', function (Blueprint $table) {
...
$table->unsignedBigInteger('member_id');
$table->foreign('member_id')->references('id')->on('members');
});
}
public function up()
{
Schema::create('skills', function (Blueprint $table) {
...
$table->unsignedBigInteger('member_skill_id');
$table->foreign('member_skill_id')->references('id')->on('member_skills');
});
}
more:https://laravel.com/docs/8.x/migrations#foreign-key-constraints
You should try using the id of the member table as the foreign key rather than the name in the member_skills schema
public function up()
{
Schema::create('member_skills', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('member_id');
$table->string('skill');
$table->foreign('member_id')->references('id')->on('members');
});
}
You are getting this error because you are trying to reference name in the member table which is already a foreign key to the users table.
You can access the name of the member through the id foreign key in your blade.

Laravel Eloquant Delete Child Table Row - onDelete('cascade') is not deleting child table row

Thank you in advance
I have 2 tables as below
1) users
2) reviews
The schema I have created is like below
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('first_name',100)->nullable();
$table->timestamps();
});
Schema::create('reviews', function (Blueprint $table) {
$table->id();
$table->bigInteger('user_id')->unsigned();
$table->string('name',100)->nullable();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
When i am deleting the user, it is not deleting reviews belongs to the deleted user
I am deleting user like below
User::where('id',1)->delete();
is there any short and simple and perfect way to do them for all the eloquent models?
you can try this code in your parent model :
public static function boot()
{
parent::boot();
static::deleting(function ($model) {
$model->relations()->delete();
});
}
*update for softDeletes
public static function boot()
{
parent::boot();
static::deleting(function ($model) {
if($model->isForceDeleting()){
$model->relations()->delete();//or forceDelete if child also using softDelete
});
}
}

I have a table 'posts' which contains a foreign key 'user_id, how can i add that key to table on migration?

this is the migration
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->timestamps();
i have tried to do it with this lines
$table->bigInteger(‘user_id’)->unsigned()->nullable()->default(null);
$table->foreign(‘user_id’)->references(‘id’)->on(‘users’)->onDelete(‘cascade’);
what i did
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->integer(‘user_id’)->unsigned()->nullable()->default(null);
$table->foreign(‘user_id’)->references(‘id’)->on(‘users’)-
>onDelete(‘cascade’);
what i get
ErrorExceptionenter
Use of undefined constant ‘user_id’ - assumed '‘user_id’' (this will throw an Error in a future version of PHP)
#Mirage Three questions:
why are you using backticks instead of single quotes?
why are you using just $table->id(); when it should be $table->integer('id');?
why are you using $table->timestamps(); when it should be $table->timestamp('created');?
This migration with tweaks to be single quotes instead of backticks, correctly using $table->id(); and $table->timestamp('created'); works just fine for me:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class Posts extends Migration
{
public function up()
{
if(!Schema::hasTable('posts')) {
Schema::connection('migrate')->create('testPosts', function (Blueprint $table) {
$table->integer('id');
$table->integer('user_id')->unsigned()->nullable()->default(null);
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamp('created');
});
}
}
public function down()
{
if(Schema::hasTable('posts')) {
Schema::connection('migrate')->dropIfExists('posts');
}
}
}

how to rename foreign key in Laravel

I want to rename the foreign key in Laravel.
This is how, I have created it:
Schema::create('holidays', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->integer('account_id')->unsigned();
$table->date('holiday_date');
});
if (Schema::hasTable('accounts')) {
Schema::table(
'holidays',
function (Blueprint $table) {
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
}
);
}
And now, I want to change account_id to engagement_id. How to do that?
It should be something like this :
Note : Before Renaming Foreign, You Must Need To Delete Old Foreign And Assign New One
class RenameColumn extends Migration
{
public function up()
{
Schema::table('holidays', function(Blueprint $table) {
$table->dropForeign('holidays_account_id_foreign');
$table->renameColumn('account_id', 'engagement_id');
$table->foreign('engagement_id')->references('id')->on('accounts')->onDelete('cascade');
});
}
public function down()
{
Schema::table('holidays', function(Blueprint $table) {
$table->dropForeign('holidays_engagement_id_foreign');
$table->renameColumn('account_id', 'engagement_id');
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
});
}
}
What #rborum explained requires doctrine/dbal package to be installed. Else you could directly execute sql query to rename your key or do any other changes.
I was able to do this without dropping the column.
Very simply:
public $oldIndex = 'old_constraint_name_foreign';
public $newIndex = 'new_constraint_name_foreign';
public $oldColumn = 'old_column_name';
public $newColumn = 'new_column_name';
Schema::table('my_table', function (Blueprint $table) {
$table->renameIndex($this->oldIndex, $this->newIndex);
$table->renameColumn($this->oldColumn, $this->newColumn);
});
You need to make a new migration with:
php artisan make:migration rename_column
With this inside:
class RenameColumn extends Migration
{
public function up()
{
Schema::table('accounts', function(Blueprint $table) {
$table->renameColumn('account_id ', 'engagement_id');
});
}
public function down()
{
Schema::table('accounts', function(Blueprint $table) {
$table->renameColumn('account_id ', 'engagement_id');
});
}
}
Then execute your migration:
php artisan migrate
If you do not already have it, you will need Doctrine. You can get this via composer with
composer require doctrine/dbal

Foreign Key in Laravel 5.1 - NO Relationship

Need Help guys! Whats wrong with my migrations, It's not creating a relationship between users table and posts table. Here's what I did:
migrate users table
create posts table
migrate posts table with foreign key
Users Migration:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('users');
}
}
Posts Migration:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('title', 255);
$table->text('content');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('posts');
}
}
Nothing Happen with my database. Take a look at my database:
Compared with this:
.. I'm using Laravel 5.1
You need to add it in two step. Schema::create() is only used to create table.
To add relation you need to write it within Schema::table().
Try following :
In CreatePostsTable :
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('title', 255);
$table->text('content');
$table->timestamps();
});
Schema::table('posts', function($table) {
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}