私が大嫌いなCakePHPを好きになるまで　第2章　〜Migration / Seeding編〜

なぜこんなタイトルなのかと、１章は[こちら]()から

## 第２章 マイグレーション、シーディング

では、１章でデータベースの接続と、無事bakeコマンドが通ることを確認できたので
次にmigrationとseederの設定をしていきます。

### Migration（テーブルの作成）

#### 前準備
公式によると、マイグレーションを使うにはプラグインを入れないといけないらしい。
入れとけよ。

```
bin/cake plugin load Migrations
```

#### Migrationファイルの作成
```
$ bin/cake bake migration CreateProducts name:string description:text created modified
```

CakePHPで作る場合、とりあえずCreate（テーブル名）の後にオプションでカラムと型を指定して実行する。
※idはデフォルトであります。

とりあえず作ってしまって、後から書き換えればいいのでファイル作るときは`name:string`とだけやってあとから直しても良さそう。

```YYYYMMDDTTTT_CreateProducts.php
<?php
use Migrations\AbstractMigration;

class CreateProducts extends AbstractMigration
{
    public function change()
    {

        $table = $this->table('products');
        $table->addColumn('name', 'string', [
            'default' => null,
            'limit' => 255,
            'null' => false,
        ]);
        $table->addColumn('price', 'biginteger', [
            'default' => null,
            'limit' => 255,
            'null' => false,
        ]);
        $table->addColumn('description', 'text', [
            'default' => null,
            'null' => false,
        ]);
        $table->addColumn('created', 'datetime', [
            'default' => null,
            'null' => false,
        ]);
        $table->addColumn('modified', 'datetime', [
            'default' => null,
            'null' => false,
        ]);
        $table->create();
    }
}

```

priceをintegerで指定すると、なぜか出来上がるのはtinyint(4)ってなる謎。
bigintegerにするとbigint(20)になるのでまぁいいか。
この辺は勉強して別の記事でまとめてみます。
あとは普通に実行コマンドを打つだけ。

```
$ bin/cake migrations migrate
```

#### ちょっと知識系
マイグレーションファイルは「データベースのテーブルを操作する」ものになります。
CakePHPの性質として、カラム名やファイル名に結構依存するので、カラム名やテーブル名には特に慎重にならなくてはいけません。
ちなみに、マイグレーションファイルは以下のようなファイル名と操作が可能です。

---
### マイグレーションファイル名

(/^(Create)(.*)/) 指定したテーブルを作成します。

(/^(Drop)(.*)/) 指定したテーブルを削除します。フィールドの指定は無視されます。

(/^(Add).*(?:To)(.*)/) 指定したテーブルにカラム追加します。

(/^(Remove).*(?:From)(.*)/) 指定のテーブルのカラムを削除します。

(/^(Alter)(.*)/) 指定したテーブルを変更します。 CreateTable と AddField の別名。

(/^(Alter).*(?:On)(.*)/) 指定されたテーブルのフィールドを変更します。

マイグレーションの名前に アンダースコアー_形式 を使用できます。例: create_products

---

### Seeder（ダミーデータの作成）
テーブルを作成したとはいえ、まぁ空っぽでは動作確認がしにくいですよね。
なので、seedという機能を使ってテストデータを入れていきます。

#### seederファイルの作成
```
$ bin/cake bake seed Products
```
はい、ファイルはconfig/Seeds上にできているので編集していきましょう。
今回は簡単な方法として、自分でテストデータを作っていきます。
idとcreated_atのようなタイムスタンプは自動で入るので、編集するであろうカラムのみテストデータの記載をしていきます。

```ProductsSeed.php
<?php
use Migrations\AbstractSeed;

/**
 * Products seed.
 */
class ProductsSeed extends AbstractSeed
{

    public function run()
    {
        $datetime = date('Y-m-d H:i:s');
        $data = [
            [
                'name' => 'pen',
                'price' => 150,
                'description' => '普通のペンです',
                'created' => $datetime,
                'modified' => $datetime,
            ],
            [
                'name' => 'note',
                'price' => 200,
                'description' => '普通のノートです',
                'created' => $datetime,
                'modified' => $datetime,
            ],
            [
                'name' => 'case',
                'price' => 1000,
                'description' => '高級なケースです',
                'created' => $datetime,
                'modified' => $datetime,
            ],
            [
                'name' => 'drink',
                'price' => 150,
                'description' => '変なお茶です',
                'created' => $datetime,
                'modified' => $datetime,
            ],
            [
                'name' => 'bottle',
                'price' => 500,
                'description' => 'ペンギンのマイボトルです',
                'created' => $datetime,
                'modified' => $datetime,
            ],
        ];

        $table = $this->table('products');
        $table->insert($data)->save();
    }
}
```

#### 呼び出し用のSeedファイルの作成
手段はなんでもいいですが、config/Seedsの中に`DatabaseSeed.php`を作成してファイルを以下のようにしてください。

```DatabaseSeed.php
<?php
use Migrations\AbstractSeed;

class DatabaseSeed extends AbstractSeed
{
    public function run()
    {
        $this->call('ProductsSeed');

    }
}
```

##### 解説
Laravelをやってるとこれは標準装備なんですが、
SeederないしMigration,bake allするときは実行する順番が重要です。
例えば、usersテーブルに権限を管理するrole_idテーブルがあり、権限は別のrolesテーブルで管理していたとします。
その場合、もし先にusersテーブルを作成しようとすると、rolesテーブルが存在しないので**role_idって何？**って怒られてしまいます。
なので、実行する順番を自分で操作するの必要があります。

bake allするときは自分で実行順番を気をつければいいですが、できればまとめてガバッと作りたいですよね。
その時にいきなり`bin/cake migrations seed`で実行してもアルファベット順に処理されてしまいます。
そこで、このようにシーダーを呼び出すだけのファイルを作成し、実行順番を操作してあげることでまとめて処理ができます。

全てのシーダーファイルが準備できたら、`bin/cake migrations seed --seed DatabaseSeed`と実行したらまとめて実行できます。

```
$ bin/cake migrations seed --seed DatabaseSeed
```

はい、完了です。

次は、フロント部分かなと。
フォームヘルパーの苦しさ再びか、、、