lat4732's avatar
Level 12

How to deal with migrating tables when both must have relationship between them

Hello everyone!

I've just changed the structure of 2 tables in my database. One of them is reviews table and the other is review_reports table. Both of them doesn't exists right now in my database. Both of them have relationship to the other one.

reviews:

Schema::create('reviews', function (Blueprint $table) {
  ....
$table->bigInteger('removed_because_of_report_id')->unsigned()->nullable();
  ....
$table->foreign('removed_because_of_report_id')->references('id')->on('review_reports');
});

review_reports

Schema::create('review_reports', function (Blueprint $table) {
...
$table->unsignedBigInteger('review_id');
...
$table->foreign('review_id')->references('id')->on('reviews');
});

And obviously when I try to run php artisan migrate I get the following error when it came to reviews table:

Undefined table: 7 ERROR:  relation "review_reports" does not exist (SQL: alter table "reviews" add constraint "reviews_removed_because_of_report_id_foreign" foreign key ("removed_because_of_report_id") references "review_reports" ("id"))

And when I try to manually migrate the review_reports I get:

SQLSTATE[42P01]: Undefined table: 7 ERROR:  relation "reviews" does not exist (SQL: alter table "review_reports" add constraint "review_reports_review_id_foreign" foreign key ("review_id") references "reviews" ("id"))

How can I deal with that? Theoretically I can migrate no table at this point because they both need each other in order to join the database.

0 likes
13 replies
tykus's avatar

Make another migration to establish to foreign key relationships after the two other migrations have run

1 like
lat4732's avatar
Level 12

@Nakov a review can have many reports. But when the administrator decides to remove the review due to a report by someone, I must have this information somewhere. And my thought was to make a column that has a default value of null, and when the review is removed in this column to store the ID of the report for which it was removed so I can retrieve information about why this review was removed. Something like documentation of why this review was removed

Nakov's avatar

@Laralex I am not sure I get it. If the review or report is removed then how will the ID of it help when you won't have the entity? And if it is just for logging purposes why do you need the foreign ID then? You can just keep in the nullable bigInteger column I guess.

lat4732's avatar
Level 12

@Nakov If a review have 1 report about adveritsing and 1 report about verbal abuse and the administrator decide to remove this review how would you know based on which report he removed it if you don't record it somewhere? That's my logic. Maybe my logic is totally wrong, might be because my mind is blowing off. Correct me if I'm wrong somewhere

lat4732's avatar
Level 12

@Nakov And maybe you're right. I can just put the ID of the report in the reviews table without any relations and stuff at all.

Nakov's avatar

@Laralex I would make the Review table allow soft deletes, same with the reports table, and the reports table will have a foreign key to the review, which when the Admin deletes the review will also "soft delete" the reports, and you can still keep everything in place and know which is referenced by what. You will still be able to see all the removed reviews in a separate "admin" page if you want to, restore them and do whatever you want without loosing track. At least that's what I am thinking of.

Nakov's avatar

@Laralex I am saying you should put the review_id in the reports table, not the other way around, since you can have multiple reports for the same review, and not the other way around :) That's the proper One to Many relationship in your case.

Based on the example you gave me above.

Nakov's avatar

@Laralex :D Okay. You are making the migrations now and it is re-constructing :D

I hope it makes sense to you at least. Have fun!

lat4732's avatar
Level 12

@Nakov The app has 31 tables and like 50 pages. Your suggestion is absolutely right, but I'm developing it alone. If I have to do something, re-think about it and then re-construct it then I think the app will be finished in 2024 :D Thanks for your time!

lalitesh's avatar
lalitesh
Best Answer
Level 4

Try this, it will work:

reviews:

Schema::create('reviews', function (Blueprint $table) {
  ....
  ....
});

review_reports

Schema::create('review_reports', function (Blueprint $table) {
	...
	$table->unsignedBigInteger('review_id');
	...
	$table->foreign('review_id')->references('id')->on('reviews');
});

Schema::table('reviews', function (Blueprint $table) {
	$table->bigInteger('removed_because_of_report_id')->unsigned()->nullable();
	$table->foreign('removed_because_of_report_id')->references('id')->on('review_reports');
});

Basically, it is executing another migration to edit the reviews table, once both the initial tables are created. ( @tykus suggested the same )

1 like

Please or to participate in this conversation.