まず我々が最初に行っていたのはテーブルの定義が変更となる度に、そのテーブルを持つマイグレーションファイルをロールバックして、修正し再度マイグレーションする方法です。以前の内容でも触れましたが、以下のSQLで取得できるbatchの値を変更することでロールバックの対象にする方法です。
batchの値を最大値にupdateすることで、マイグレーションの順番を強引に入れ替えて強制的にロールバックの対象となります。例えばSQLで取得した結果が以下の状態だっとします。
カラム定義の共通化
ここからはカラム定義の管理の仕方を考えます。以下のupメソッドがある2つのテーブルがあるとします。
1つ目のテーブルは上で出てきたサンプルテーブルです。
public $tbl_name='samples';//テーブル名のプロパティ追加
public function up()
{
Schema::create($this->tbl_name, function (Blueprint $table) {
$table->increments('id');
$table->string('name',255);
$table->string('group_cd',5)->nullable();
$table->smallInteger('amount');
$table->double('rate', 5, 2);
});
// add comments
DB::statement("ALTER TABLE ".DB::getTablePrefix().$this->tbl_name." COMMENT 'サンプルテーブル'");
}
2つ目のテーブルはグループテーブルです。1つ目のサンプルテーブルの「group_cd」にはこのグループテーブルに存在する「group_cd」が登録されるものとします。
public $tbl_name='groups';//テーブル名のプロパティ追加
public function up()
{
Schema::create($this->tbl_name, function (Blueprint $table) {
$table->increments('id');
$table->string('group_cd',5);
$table->string('name',255);
});
// add comments
DB::statement("ALTER TABLE ".DB::getTablePrefix().$this->tbl_name." COMMENT 'グループテーブル'");
}
ここで「group_cd」は5桁の文字列型(MySQLではVARCHARで作成されます)となっています。この「group_cd」の桁数や型を変更することになった場合、これら2つのマイグレーションファイルを変更する必要が出てきます。このカラムがもっと多くのテーブルに使用されている場合、変更するだけでも結構な作業量になるのでどうにかして、効率化したいと思います。
といってもやることは簡単で、カラムの定義を関数で行ってしまおうというものです。
$table->string('group_cd',5);
としている部分を、例えば
columnDef('group_cd');
というようにカラム名を渡すと共通の定義ができるようにするイメージです。我々の場合、Laravelのファサード(仮にMigrationFuncとします)を作成しています。またBlueprintオブジェクトの$tableにカラムの定義をすることになるので$tableを渡す必要があります。こんな感じです。
MigrationFunc::columnDef($table,'group_cd');
このMigrationFuncファサードのメソッドによって、「$table->string('group_cd',5);」が実行されるように実装しています。ただ2つのupメソッドの設定を見れば分かる通り、テーブルによってはnullableにできる必要があります。MigrationFuncファサードのメソッドの引数の定義は以下のようになります。(実装部分については省略します⇒こちらに記載しました)
public function columnDef(Blueprint $table,$column_name,$nullable_flg=false){}
カラムの共通定義は連想配列などで以下のような感じで、MigrationFuncファサード内に設定しておきます。
$column_def = [
'id' => ['type'=>'increments','comment'=>'ID'],
'name' => ['type'=>'string','length'=>255,'comment'=>'名前'],
'group_cd' => ['type'=>'string','length'=>5,'comment'=>'グループCD'],
];
渡ってきた$colNameから、カラムの共通定義の設定を$tableに行い、必要に応じて追加される設定(この場合はnullable)を行うようにします。このメソッドをマイグレーションファイルに設定します。
1つ目のサンプルテーブル
public $tbl_name='samples';//テーブル名のプロパティ追加
public function up()
{
Schema::create($this->tbl_name, function (Blueprint $table) {
MigrationFunc::columnDef($table,'id');
MigrationFunc::columnDef($table,'name');
MigrationFunc::columnDef($table,'group_cd',true);
$table->smallInteger('amount');
$table->double('rate', 5, 2);
});
// add comments
DB::statement("ALTER TABLE ".DB::getTablePrefix().$this->tbl_name." COMMENT 'サンプルテーブル'");
}
2つ目のグループテーブル
public $tbl_name='groups';//テーブル名のプロパティ追加
public function up()
{
Schema::create($this->tbl_name, function (Blueprint $table) {
MigrationFunc::columnDef($table,'id');
MigrationFunc::columnDef($table,'group_cd');
MigrationFunc::columnDef($table,'name');
});
// add comments
DB::statement("ALTER TABLE ".DB::getTablePrefix().$this->tbl_name." COMMENT 'グループテーブル'");
}
このようにしておくことで特定のカラムで変更があった場合、カラムの共通定義の設定を変更し、対象となるマイグレーションファイルをロールバックしてマイグレーションをすることで変更が反映されます。このときマイグレーションファイル自体には何の修正もする必要がありません。共通定義から同じ設定が対象のカラムにされることになります。サンプルテーブルでは一部のカラムの定義は$tableのままになっています。複数のテーブルで使用しないカラムは通常の設定で行っても良いかもしれません。
この方法の問題点はあるカラムの変更がある場合、そのカラムを使用しているマイグレーションファイルを洗い出して、ロールバックできるようにする作業が必要になることです。こちらを参考にして、カラム名を指定してSQLを流せば、使用しているテーブルを確認することはできます。
Select * From information_schema.columns I1
Where I1.table_schema = 'DB_NAME'
And I1.column_name='COLUMN_NAME';
ただし、 MigrationFunc::columnDefではなく標準の設定方法で定義したカラムも同じカラム名であれば取得されることになりますので注意して下さい。MySQLの場合、カラムに対してコメントの設定が可能です。 我々の場合、MigrationFunc::columnDefで設定したカラムは特定のコメントが付くようにして、標準の設定方法のカラムと区別するようにしてます。