increments('id'); $table->timestamps(); // note that a revision may be shared by multiple tables, thus a proposal may also apply to different tables $table->unsignedInteger('table_id')->index()->nullable(); // table this proposal was written for $table->unsignedInteger('revision_id')->index(); // parent revision (applying it to a different revisions may cause conflicts) $table->unsignedInteger('author_id')->index(); $table->text('note')->nullable(); $table->jsonb('changes'); // the actual meat of the changeset is stored here $table->foreign('revision_id')->references('id')->on('revisions') ->onDelete('cascade'); // a proposal without the revision is useless // deleting the table must NOT delete the proposals, as they may be applicable to forks sharing the revision $table->foreign('table_id')->references('id')->on('tables') ->onDelete('set null'); // deleting author wipes their proposals $table->foreign('author_id')->references('id')->on('users') ->onDelete('cascade'); }); // add FK to revisions to point to the source proposal Schema::table('revisions', function (Blueprint $table) { $table->foreign('proposal_id')->references('id')->on('proposals') ->onDelete('set null'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('proposals'); } }