tjtjtjのメモ

自分のためのメモです

yiiカイドを横断してみる リレーション編(1/3) - テーブル作成

初見の人がリレーショナルアクティブレコード - ガイドをみてテーブルを作成しモデルを作成しリレーション定義しそれを検証できるんだろうか、ガイド記事は断片的過ぎやしないか、横断的なまとまった情報ほしいなあ、と思い書いてみました。。
yiiのカイドページを参照しつつ、リレーション作成とその検証まで辿ります。DBエンジンにはMySQL.Innodbを使います。

アジェンダ

yii のガイドを辿ってデータベース接続からリレーションの検証までを辿ります。Yiiアプリケーションの生成、データベースの生成(CREATE DATABASE)、PHPUnitのインストールは済ませてください。

作成するテーブル、リレーションはリレーショナルアクティブレコード - ガイドを参照してください。

データベース接続の確立

データベース接続はデータベース接続の確立を参照しつつ設定します。作成するテーブルには接頭子「tbl_」が付いています。これを main.php, console.php に設定します。console.phpで定義した設定は、テーブル生成時使われます。

/webapp/protrected/config/main.php

<?php
return array(
	'components'=>array(
		'db'=>array(
			'connectionString' => 'mysql:host=localhost;dbname=test',
			'emulatePrepare' => true,
			'username' => 'root',
			'password' => '',
			'charset' => 'utf8',
			'tablePrefix' => 'tbl_', // <<< ここに接頭子を定義する
		),
	),
);

/webapp/protrected/config/console.php

<?php
return array(
	'components'=>array(
		'db'=>array(
			'connectionString' => 'mysql:host=localhost;dbname=test',
			'emulatePrepare' => true,
			'username' => 'root',
			'password' => '',
			'charset' => 'utf8',
			'tablePrefix' => 'tbl_', // <<< ここに接頭子を定義する
		),
	),
);

マイグレーション作成

マイグレーションを作成します。マイグレーションは「yiic migrate create <マイグレーション名>」で生成します。今回はファーストリリースということでマイグレーション名「first_release」としました。

> cd webapp\protected
> yiic migrete create first_release

次に生成したマイグレーションにテーブル生成スクリプトを書きます。スキーマを操作するクエリをビルドする - クエリビルダ - ガイドを参照してください。
テーブル名は「tbl_post」としてもいいですが、{{}}でブレースすると接頭子「tbl_」を付与してくれるので利用します。
エンジンを念のためINNODBにしています。

/webapp/protrected/migrate/m110720_122652_first_release.php

<?php
class m110720_122652_first_release extends CDbMigration
{
	public function up()
	{
 		$this->createTable('{{post}}', array(
			'id' => 'pk',
			'title' => 'string NOT NULL',
			'content' => 'text',
			'create_time' => 'datetime',
			'author_id' => 'integer',
 		));
 		$this->execute('ALTER TABLE {{post}} ENGINE = INNODB;'); 
 		$this->createTable('{{post_category}}', array(
			'post_id' => 'integer',
 			'category_id' => 'integer',
 		));
 		$this->execute('ALTER TABLE {{post_category}} ENGINE = INNODB;'); 
 		$this->createTable('{{category}}', array(
			'id' => 'pk',
 			'name' => 'string NOT NULL',
 		));
 		$this->execute('ALTER TABLE {{category}} ENGINE = INNODB;'); 
 		$this->createTable('{{user}}', array(
			'id' => 'pk',
 			'username' => 'string NOT NULL',
 			'password' => 'string',
 			'email' => 'string',
 		));
 		$this->execute('ALTER TABLE {{user}} ENGINE = INNODB;'); 
 		$this->createTable('{{profile}}', array(
			'owner_id' => 'pk',
 			'photo' => 'binary',
 			'website' => 'string',
 		));
 		$this->execute('ALTER TABLE {{profile}} ENGINE = INNODB;'); 

 		$this->addForeignKey('fk_post_owner_id', '{{post}}',
 			'author_id', '{{user}}', 'id', 'CASCADE', 'CASCADE');
 		$this->addForeignKey('fk_profile_owner_id', '{{profile}}',
 			'owner_id', '{{user}}', 'id', 'CASCADE', 'CASCADE');
 		$this->addForeignKey('fk_post_category_1', '{{post_category}}',
 			'post_id', '{{post}}', 'id', 'CASCADE', 'CASCADE');
 		$this->addForeignKey('fk_post_category_2', '{{post_category}}',
 			'category_id', '{{category}}', 'id', 'CASCADE', 'CASCADE');
	}

	public function down()
	{
 		$this->dropForeignKey('fk_post_owner_id', '{{post}}');
 		$this->dropForeignKey('fk_profile_owner_id', '{{profile}}');
 		$this->dropForeignKey('fk_post_category_1', '{{post_category}}');
 		$this->dropForeignKey('fk_post_category_2', '{{post_category}}');

		$this->dropTable('{{post}}');
		$this->dropTable('{{post_category}}');
		$this->dropTable('{{category}}');
		$this->dropTable('{{user}}');
		$this->dropTable('{{profile}}');
	}
}

テーブル生成 - マイグレーションからテーブルを生成する

「yiic migrate」でマイグレーションを適用し、テーブルを生成します。

> cd \webapp\protected\
> yiic migrate

Yii Migration Tool v1.0 (based on Yii v1.1.8)

Total 1 new migration to be applied:
    m110720_122652_first

Apply the above migration? [yes|no] y
*** applying m110720_122652_first
    > create table {{post}} ... done (time: 0.096s)
    > create table {{post_category}} ... done (time: 0.068s)
    > create table {{category}} ... done (time: 0.111s)
    > create table {{user}} ... done (time: 0.151s)
    > create table {{profile}} ... done (time: 0.077s)
    > add foreign key fk_post_owner_id: {{post}} (author_id) references {{user}}
 (id) ... done (time: 0.152s)
    > add foreign key fk_profile_owner_id: {{profile}} (owner_id) references {{u
ser}} (id) ... done (time: 0.178s)
    > add foreign key fk_post_category_1: {{post_category}} (post_id) references
 {{post}} (id) ... done (time: 0.152s)
    > add foreign key fk_post_category_2: {{post_category}} (category_id) refere
nces {{category}} (id) ... done (time: 0.143s)
*** applied m110720_122652_first (time: 0.002s)


Migrated up successfully.

作成したテーブル、外部キーをphpmyadminとかで確認してください。