0
votes

I've and interesting scenario, I would like to implement in Laravel 5. I have 2 tables.

  1. Users ( Holds the sites users )

  2. Media ( Holds the sites images, documents, svg-s, etc... )

My technical constraints are:

  1. Every user has a profile picture and only one profile picture
  2. 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

  1. Migrating USERS table
  2. 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?

1
Use another migration to create your foreign keys after both tables are created. If you get a foreign key constraint error on seeding you can run DB::statement('SET FOREIGN_KEY_CHECKS=0;');.thefallen

1 Answers

1
votes

Easy way to make foriegn key in laravel

public function up()
{
    Schema::create('bank_user_details', function (Blueprint $table) {
        $table->foreign('country')->references('id')->on('country')
                      ->onUpdate('cascade')->onDelete('cascade');

    });
}