I've and interesting scenario, I would like to implement in Laravel 5. I have 2 tables.
Users ( Holds the sites users )
Media ( Holds the sites images, documents, svg-s, etc... )
My technical constraints are:
- Every user has a profile picture and only one profile picture
- Every media has an Author
These contraints I interpret as logical columns on Users table has a column - profile_image_id (reference to the Media table id column) Media table has a column - author_id (reference to the Users table id column)
This works out well, but becomes problematic when I want to use artisan migrations.
my migrations run in this order
- Migrating USERS table
- Migrating MEDIA table
My migrations have foreign keys being set as
USERS MIGRATION
$table->foreign('profile_image_id')->references('id')->on('media')->onDelete('restrict')->onUpdate('cascade');
MEDIA MIGRATION
$table->foreign('author_id')->references('id')->on('users')->onDelete('restrict')->onUpdate('cascade');
The command I use is
php artisan migrate:refresh --seed
The problem is that when creating the users table, the media table doesn't exist as of yet. And when trying to add the foreign key relation to media table, it produces a SQL error that the media table doesn't exist.
What I did?
I created a function on Users table migration that I ran after the seeding functions had finished
/**
* Veyzon
*
* To be run after the regular run functions on all tables
* have run
*/
public static function delayed_up() {
Schema::table('users', function (Blueprint $table) {
$table->foreign('profile_image_id')->references('id')->on('media')->onDelete('restrict')->onUpdate('cascade');
});
}
This worked out fine and dandy, but when remigrating, then Media table will not delete due to the fact that the user table still has records, where there are profile_image_id-s with values.
Now I thought I will add a few lines of code to the Media tables "down" function, that will set all the USERS table profile_media_id-s to null, but I don't really like this as this seems to tie my separate migration files together and when I declare this as architecturally normal, then this will become a bad practice.
What would you guys do, to create bidirectional One-to-One foreign key relations and integrate them into Laravel migrations?
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
. – thefallen