Laravel migrations change foreign key to be nullOnDelete() and nullable(true) - laravel

I have this migration where I created a foreign key the first time:
Schema::table('user_plays_quizzes', function (Blueprint $table) {
$table->bigInteger('quiz_id')->unsigned()->change();
$table->foreign('quiz_id')->references('id')->on('quizzes');
});
Now I have a new migration, where I want to update this foreign key to be nullable(true) and to be nullOnDelete().
I tried it so many times, but there are always errors, I feel like this is the closest approach:
Schema::table('user_plays_quizzes', function (Blueprint $table) {
$table->bigInteger('quiz_id')->unsigned()->nullable(true)->change();
$table->foreign('quiz_id')->references('id')->on('quizzes')->nullOnDelete();
});
Sadly it also does not work:
SQLSTATE[HY000]: General error: 1005 Can't create table d039e62e.user_plays_quizzes (errno: 121
"Duplicate key on write or update") (SQL: alter table user_plays_quizzes add constraint user_plays_quizzes_quiz_id_foreign for
eign key (quiz_id) references quizzes (id) on delete set null)
No Idea how to solve it. I cant even drop the keys and recreate them aswell. Maybe someone has an idea how I can update it with a migration

Why can't you drop the key and recreate it?
public function up()
{
Schema::table('user_plays_quizzes', function (Blueprint $table) {
// Drop fk constraint on quiz_id column
$table->dropForeign(['quiz_id']);
// Alter quiz_id column
$table->bigInteger('quiz_id')->unsigned()->nullable(true)->change();
// Add new fk constraint on quiz_id column
$table->foreign('quiz_id')->references('id')->on('quizzes')->nullOnDelete();
});
}
public function down()
{
Schema::table('user_plays_quizzes', function (Blueprint $table) {
// Drop fk constraint on quiz_id column
$table->dropForeign(['quiz_id']);
// Restore quiz_id column to how it was before
$table->bigInteger('quiz_id')->unsigned()->nullable(false)->change();
// Restore original fk constraint on quiz_id column
$table->foreign('quiz_id')->references('id')->on('quizzes');
});
}

Related

Laravel 7 General error: 1005 Can't create table `edmart`.`cancelled_ex ps` (errno: 121 "Duplicate key on write or update")

Hi there is have looked for solutions on Stack an couldn't solve my problem.
I am Using Laravel 7.x. At first my migrations where working properly but when i changer$table->foreignId("exp_id")->constrained("expenses")->index(); to $table->foreignId("fk_expense")->constrained("expenses")->index();, it started to show this error on migration
SQLSTATE[HY000]: General error: 1005 Can't create table `edmart`.`cancelled_ex
ps` (errno: 121 "Duplicate key on write or update") (SQL: alter table `cancelled
_exps` add constraint `1` foreign key (`fk_expense`) references `expenses` (`id`
))
Bellow are the migration file for expenses
public function up(){
Schema::create('expenses', function (Blueprint $table) {
$table->id();
$table->foreignId("user_id")->constrained("users")->index();
$table->string("desc");
$table->string("amount");
$table->string("status");
$table->timestamps();
});
}
cancelled expenses migration files
public function up()
{
Schema::create('cancelled_exps', function (Blueprint $table) {
$table->id();
$table->foreignId("fk_expense")->constrained("expenses")->index();
$table->string('viewed');
$table->timestamps();
});
}
I tried to remove the database and create a new one but still it failed.
Update:
All other migrations work properly except cancelled_exps
i changed the $table->foreignId("fk_expense")->constrained("expenses")->index() to
$table->foreignId("expences_id")->constrained()
$table->index('expense_id');
I changed the foreign key column name to expense_id hence i don't
have to specify the expenses table in constrained() chained
method.
I also changed the way i was chaining the index.
The whole migration file looks like this....
public function up()
{
Schema::create('cancelled_exps', function (Blueprint $table) {
$table->id();
$table->foreignId("expense_id")->constrained();
$table->index("expense_id");
$table->string('viewed');
$table->timestamps();
});
}

Why it appears the error "General error: 1005 Can't create table"?

I have these two migration files one to create a faq_channels table and another to create a faq_questions table. However, I'm not understanding why it is showing an error:
SQLSTATE[HY000]: General error: 1005 Can't create table `test`.`faq_questions` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `faq_questions` add const
raint `faq_questions_channel_id_foreign` foreign key (`channel_id`) references `faq_channels` (`id`) on delete cascade)
Do you know why?
// create_faq_channels_table
public function up()
{
Schema::create('faq_channels', function (Blueprint $table) {
$table->id();
$table->string('channel');
$table->text('description');
$table->timestamps();
});
}
// create_faq_questions_table
Schema::create('faq_questions', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('channel_id');
$table->string('question');
$table->text('response');
$table->timestamps();
$table->foreign('channel_id')->references('id')->on('faq_channels')->onDelete('cascade');
});
I have these two migration files one to create a faq_channels table
and another to create a faq_questions table.
Make sure that migration file for 'faq_channels' table runs before the migration file for 'faq_questions' table. Generally this type of error rises when the parent table is not created before declaring foreign key constraint.
Also edit your migration files according to Talha F.'s answer.

Foreign key constraint is incorrectly formed, Laravel

I try to migrate db, but I got an error, and I am not sure why. Not sure what is "incorrectly formed".
//First Table
Schema::create('lkp_anime_lists', function (Blueprint $table) {
$table->id();
//more columns here
});
//Second one
Schema::create('lkp_cards', function (Blueprint $table) {
$table->id();
$table->integer('lkp_anime_list_id');
});
Schema::table('lkp_cards', function ($table) {
$table->foreign('lkp_anime_list_id')
->references('id')
->on('lkp_anime_lists')
->onDelete('cascade');
});
SQLSTATE[HY000]: General error: 1005 Can't create table anime_db.lkp_cards (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table lkp_cards add constraint lkp_cards_lkp_anime_list_id_foreign foreign key (lkp_anime_list_id) references lkp_anime_lists (id) on delete cascade)
You should use
$table->unsignedBigInteger('lkp_anime_list_id')
instead because of primary and foreign keys should be in the same data type
This works for me
$table->bigInteger('lkp_anime_list_id')->unsigned();
for Laravel version 6+

Delete each corresponding row in One-to-One relationship on delete of either

I am trying to learn one-to-one relations. I am using Laravel 5.5.13.
My simple app is this:
I create a App\Message. I optionally can associate a App\Task with it.
My goal:
Once a App\Task is associated, if the task is deleted, it should cascade delete the App\Message row.
And the reverse, if the App\Message is deleted, it should cascade and delete the App\Task row.
However I am having an error on migrate because the tasks_table is created AFTER the messages_table.
Here is my migration:
2017_10_15_021803_create_messages_table.php:
public function up()
{
Schema::create('messages', function (Blueprint $table) {
$table->increments('id');
$table->integer('task_id')->unsigned()->nullable();
$table->text('body');
$table->timestamps();
$table->foreign('task_id')->references('id')->on('tasks')->onDelete('cascade'); //// IF I COMMENT THIS OUT THE MIGRATION WORKS, BUT I NEED THIS IN
});
}
And for App\Task 2017_10_15_023343_create_tasks_table.php:
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->increments('id');
$table->integer('message_id')->unsigned();
$table->timestamps();
$table->foreign('message_id')->references('id')->on('messages')->onDelete('cascade');
});
}
If I comment out the $table->foreign('task_id')->references('id')->on('tasks')->onDelete('cascade'); then the migration works, BUT i need the deletion of the message when the task is deleted, and without this line that won't happen.
The error I get after running php artisan migrate is:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1005 Can't create table petfolk.#sql-42e8_16f (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table messages add constraint messages_task_id_foreign foreign key (task_id) references tasks (id) on delete set null)
[PDOException]
SQLSTATE[HY000]: General error: 1005 Can't create table petfolk.#sql-42e8_16f (errno: 150 "Foreign key constraint is incorrectly formed")
Just create third migration and move foreign key adding logic in the migration:
Schema::table('messages', function (Blueprint $table) {
$table->foreign('task_id')->references('id')->on('tasks')->onDelete('cascade');
}
It will work when both tables will be created.
A one-to-one relationship links one row in a database table to one (and only one) row in another table.
onDelete('cascade') is used when there is an intermediate, also known as a pivot, table between two tables in a many-to-many relationship. You do not need this for a one-to-one relationship because the link to the messages table only exists in the row of the tasks table (and that is being deleted).
Try this for the tasks table migration:
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->increments('id');
$table->integer('message_id')->unsigned()->nullable();
$table->foreign('message_id')->references('id')->on('messages');
$table->timestamps();
});
}

Laravel migration won't reference second foreign key

I am trying to reference the id of a product on two tables (a categories and a brands table).
public function up()
{
Schema::create('products', function($table)
{
$table->increments('id');
$table->integer('category_id')->unsigned();
$table->integer('brand_id')->unsigned();
$table->string('title');
$table->text('description');
$table->decimal('price', 6, 2);
$table->boolean('availability')->default(1);
$table->string('image');
$table->timestamps();
});
Schema::table('products', function($table){
$table->foreign('category_id')->references('id')->on('categories');
$table->foreign('brand_id')->references('id')->on('brands');
});
}
But I get the following errors:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL
: alter table `products` add constraint products_brand_id_foreign foreign k
ey (`brand_id`) references `brands` (`id`))
[PDOException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
Which is the correct way to do this?
Update
Migration public function up for the brands table
public function up()
{
Schema::create('brands', function($table){
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
Solution
Finally, the error was on the naming of the migration. Due to the fact that brands table was the most recent table I had to changed its name from: 2014_12_12_164325_create_brands_table to this 2014_10_12_164325_create_brands_table and the tables were migrated successfully.
Everything looks ok to me. Furthermore, since it only complains about the second part, the categories foreign key must've worked. I would think the brands table doesn't exist or there is something wrong there. Does the table exist and does it have a primary key "id"?
I also use
$table->engine = 'InnoDB';
at the beginning, because MyISAM doesn't support foreign keys as of now. I don't think it should be an issue in the above case, but perhaps still advisable, if you want to do foreign key restrictions on the DB level.

Resources