JobeetでYii2フレームワークを学習する(2)

この記事ではモデルの構築に必要なマイグレーションを使ったスキーマの作成からモデルの生成や初期データの投入方法について説明します。

スキーマの構成について

データベースのスキーマーは、Symfony の Jobeetと同じ構成とします。

マイグレーションの生成

準備

Yii2にはデータベースの構造(スキーマ)のバージョン管理できるマイグレーション(Migration)という機能があります。

デフォルトの状態ではこの情報を管理するディレクトリがありませんので以下のコマンドでマイグレーションディレクトリの作成とデータベースにマイグレーション管理用のテーブルを作成します。

$ yii migrate

Categoryスキーマの作成

以下のコマンドを実行してCategoryテーブルのスキーマを生成します。

$ yii migrate/create create_category_table

コマンド実行にて生成されたファイルを編集します。

migrations/m190711_041836_create_category_table.php
<?php

use yii\db\Migration;

/**
 * Handles the creation of table `{{%category}}`.
 */
class m190711_041836_create_category_table extends Migration
{
    /**
     * {@inheritdoc}
     */
    public function safeUp()
    {
        $this->createTable('{{%category}}', [
            'id' => $this->primaryKey(),
            'name' => $this->string()->notNull()->unique(),
        ]);
   }

    /**
     * {@inheritdoc}
     */
    public function safeDown()
    {
        $this->dropTable('{{%category}}');
    }
}
補足

上記の流れではスキーマ生成コマンド実行後、生成されたファイルにCategoryテーブルのカラムの内容を記述必要がある事に対し、以下のコマンドにてカラムの内容も同時に生成する事ができます。

yii migrate/create create_category_table --fields="name:string:notNull:unique"

Jobスキーマの作成

上記、Categoryスキーマと同じ要領でJobスキーマを作成します。

$ yii migrate/create create_job_table --fields="category_id:integer:notNull:foreignKey(category),type:string,company:string:notNull,logo:string,url:string,position:string:notNull,location:string:notNull,description:text:notNull,how_to_apply:text:notNull,token:string:unique,is_public:boolean:notNull:defaultValue(1),is_activated:boolean:notNull:defaultValue(0),email:string:notNull,expires_at:dateTime,created_at:dateTime,updated_at:dateTime"

Affiliateスキーマの作成

$ yii migrate/create create_affiliate_table --fields="url:string:notNull,email:string:notNull:unique,token:string,is_active:integer:notNull:defaultValue(0),created_at:dateTime"

CategoryAffiliateスキーマの作成

$ yii migrate/create create_categoryAffiliate_table --fields="category_id:integer:foreignKey(category),affiliate_id:integer:foreignKey(affiliate)"

スキーマの実行

作成した全てのスキーマを実行してデーターベースへ反映します。

$ yii migrate/up
Yii Migration Tool (based on Yii v2.0.23)

Total 4 new migrations to be applied:
        m190722_043410_create_category_table
        m190722_043513_create_job_table
        m190722_043552_create_affiliate_table
        m190722_043616_create_categoryAffiliate_table

Apply the above migrations? (yes|no) [no]:yes
*** applying m190722_043410_create_category_table
    > create table {{%category}} ... done (time: 0.055s)
*** applied m190722_043410_create_category_table (time: 0.182s)

*** applying m190722_043513_create_job_table
    > create table {{%job}} ... done (time: 0.077s)
    > create index {{%idx-job-category_id}} on {{%job}} (category_id) ... done (time: 0.027s)
    > add foreign key {{%fk-job-category_id}}: {{%job}} (category_id) references {{%category}} (id) ... done (time: 0.241s)
*** applied m190722_043513_create_job_table (time: 0.350s)

*** applying m190722_043552_create_affiliate_table
    > create table {{%affiliate}} ... done (time: 0.022s)
*** applied m190722_043552_create_affiliate_table (time: 0.037s)

*** applying m190722_043616_create_categoryAffiliate_table
    > create table {{%categoryAffiliate}} ... done (time: 0.020s)
    > create index {{%idx-categoryAffiliate-category_id}} on {{%categoryAffiliate}} (category_id) ... done (time: 0.027s)
    > add foreign key {{%fk-categoryAffiliate-category_id}}: {{%categoryAffiliate}} (category_id) references {{%category}} (id) ... done (time: 0.230s)
    > create index {{%idx-categoryAffiliate-affiliate_id}} on {{%categoryAffiliate}} (affiliate_id) ... done (time: 0.021s)
    > add foreign key {{%fk-categoryAffiliate-affiliate_id}}: {{%categoryAffiliate}} (affiliate_id) references {{%affiliate}} (id) ... done (time: 0.049s)
*** applied m190722_043616_create_categoryAffiliate_table (time: 0.351s)


4 migrations were applied.

Migrated up successfully.
補足

各テーブル毎にスキーマを実行する場合はスキーマ実行コマンドに単一の値である1を追加します。

$ yii migrate/up 1

実行したスキーマを一つ戻す(ロールバック)する場合は以下のコマンドを実行します。

$ yii migrate/down 1

モデルの生成

スキーマの生成が完了した事で、いよいよモデルを生成します。

モデルの生成はコード生成ツールのGiiのモデルジェネレーター(Model Generator)を利用します。

Table Name の項目にデータベースへ反映したcategoryを入力すると、Model Class Nameに接頭の一文字が大文字のCategoryが自動入力されるので、自動入力確認後、Previewを押下します。

Model情報入寮画面

次にGenerateを押下します。

Model プレビュー画面

Generateを押下後、modelsディレクトリ内にモデルファイルが生成が確認できますので、Categoryと同じ要領で、job、affiliate、categoryAffiliateもモデルを生成します。

初期データの投入

いよいよGiiのCRUD生成ツールでJobテーブルへのデータの登録・表示・更新・削除ができるようにしたいところですが、Jobテーブルスキーマのcategory_idは、Categoryテーブルとリレーションの関係にあり、必須項目の制限がされている為、Cateogoryのデータが無いとJobテーブルのデータを扱う事ができません。

Categoryテーブル初期データ投入ファイルの作成

以下のコマンドにて初期データ投入用のマイグレーションファイルを生成します。

$ yii migrate/create insert_category_data

生成したファイルを以下のように編集します。

migrations/m190720_072826_insert_category_data.php
<?php

use yii\db\Migration;

/**
 * Handles the creation of table `{{%category2}}`.
 */
class m190720_072826_insert_category_data extends Migration
{
    /**
     * {@inheritdoc}
     */
    public function safeUp()
    {
        $this->insert('{{%category}}', ['name' => 'Design']);
        $this->insert('{{%category}}', ['name' => 'Programming']);
        $this->insert('{{%category}}', ['name' => 'Manager']);
        $this->insert('{{%category}}', ['name' => 'Administrator']);
    }

    /**
     * {@inheritdoc}
     */
    public function safeDown()
    {
        $this->delete('{{%category}}', ['name' => 'Design']);
        $this->delete('{{%category}}', ['name' => 'Programming']);
        $this->delete('{{%category}}', ['name' => 'Manager']);
        $this->delete('{{%category}}', ['name' => 'Administrator']);
    }
}

Jobテーブル初期データ投入ファイルの作成

Jobテーブルに初期データは必要ありませんが、開発を進めるにあたり、1ページに表示するJobデータ数の確認作業など、多くのデータが必要な場合はマイグレーションにて以下の用に大量のデータを投入する事ができます。

$ yii migrate/create insert_Job_data
migrations/m190719_024003_insert_job_data.php
<?php

use yii\db\Migration;

/**
 * Class m190719_024003_insert_job_data
 */
class m190719_024003_insert_job_data extends Migration
{
    /**
     * {@inheritdoc}
     */
    public function safeUp()
    {
        $description = <<< EOM
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in.

Voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.
EOM;
        for ($i = 1; $i < 31; $i++)
        {
            $this->insert('{{%job}}', [
                'category_id' => 1,
                'type' => 'full-time',
                'company' => 'Sensio Labs('.$i.')',
                'logo' => 'sensio-labs.gif',
                'url' => 'http://www.sensiolabs.com/',
                'position' => 'Web Developer('.$i.')',
                'location' => 'Paris, France',
                'description' => $description,
                'how_to_apply' => 'Send your resume to fabien.potencier [at] sensio.com',
                'is_public' => '1',
                'is_activated' => '1',
                'token' => 'Yq9OPGoKEJ'.sprintf('%02d', $i),
                'email' => 'job@example.com',
                'expires_at' => date('Y-m-d H:i:s', strtotime("+30 day")),
            ]);
    
        }
      
        for ($i = 1; $i < 3; $i++)
        {
            $this->insert('{{%job}}', [
                'category_id' => 2,
                'type' => 'full-time',
                'company' => 'Sensio Labs('.$i.')',
                'logo' => 'sensio-labs.gif',
                'url' => 'http://www.sensiolabs.com/',
                'position' => 'Web Designer('.$i.')',
                'location' => 'Paris, France',
                'description' => $description,
                'how_to_apply' => 'Send your resume to fabien.potencier [at] sensio.com',
                'is_public' => '1',
                'is_activated' => '1',
                'token' => 'Yq9OPGoKEL'.sprintf('%02d', $i),
                'email' => 'job@example.com',
                'expires_at' => date('Y-m-d H:i:s', strtotime("+30 day")),
            ]);
    
        }

    }

    /**
     * {@inheritdoc}
     */
    public function safeDown()
    {
        for ($i = 1; $i < 50; $i++) {
            $this->delete('{{%job}}', ['id' => $i]);
        }
    }

}

初期データの反映

以下のコマンドにてデータベースへ初期データを投入します。

$ yii migrate/up
タイトルとURLをコピーしました