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

今回はモデルを作ります。

Gii準備

yiic shell のコード生成機能は、バージョン 1.1.2 以降、非推奨(depricated)となっています。

http://www.yiiframework.com/doc/guide/1.1/ja/quickstart.first-app-yiic

とのことなのでyiicを使わずGiiを使ってモデルを生成します。Giiを使うにはmain.phpへ設定が必要です。Giiを使うを参照しつつ設定します。

/webapp/protrected/config/main.php

<?php
return array(
	'modules'=>array(
		'gii'=>array(
			'class'=>'system.gii.GiiModule',
			'password'=>'pick up a password here', <<適当に変更
 		),
	),
);

Giiでモデル生成する

URL http://hostname/path/to/index.php?r=gii にアクセスします。こんなページが表示されます。
f:id:tjtjtjofthedead:20110807130702j:image:medium:right

「Table Name」にはtablePrefixを省略しないテーブル名「tbl_post」、「Model Class」には「Post」を入力しpreviewをクリックするとモデル実装のプレビューが表示されます。続いてgenerateをクリックするとPost.phpが生成されます。「Build Rerations」をチェックしておけば、外部キーに基づきリレーションも設定してくれます。

/webapp/protected/models/Post.php (の一部)

<?php
class Post extends CActiveRecord
{
	/**
	 * Returns the static model of the specified AR class.
	 * @return Post the static model class
	 */
	public static function model($className=__CLASS__)
	{
		return parent::model($className);
	}

	/**
	 * @return string the associated database table name
	 */
	public function tableName()
	{
		return '{{post}}';
	}

	/**
	 * @return array relational rules.
	 */
	public function relations()
	{
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
			'author' => array(self::BELONGS_TO, 'User', 'author_id'),
			'postCategories' => array(self::HAS_MANY, 'PostCategory', 'post_id'), //<-PostCategoryモデルを参照している
		);
	}

}

ここでもテーブル名が{{}}でブレースされていますね。その調子で計5モデルを生成します。

  • tbl_post -> Post
  • tbl_category -> Category8
  • tbl_user -> User
  • tbl_profile -> Profile
  • tbl_post_category -> PostCategory

PostモデルからpostCategoriesリーレーションでPostCategorへリレーションしていますが、本来のリレーション先はCaregoryです。これは後で修正します。

リレーションを設定する

リレーショナルアクティブレコード - ガイドのようにリレーションを定義します。大体はGiiで生成したままでいいのですが、MANY_MANYは手で修正する必要があるようです。
PostからCategoryを MANY_MANY でリレーションするよう修正します。リレーションにあわせてクラスコメントも修正します。

/webapp/protected/models/Post.php (の一部)

<?php
/**
 * This is the model class for table "{{post}}".
 *
 * The followings are the available columns in table '{{post}}':
 * @property integer $id
 * @property string $title
 * @property string $content
 * @property string $create_time
 * @property integer $author_id
 *
 * The followings are the available model relations:
 * @property User $author
 * @property Categories[] $categories  << ここ修正
 */
class Post extends CActiveRecord
{
	public function relations()
	{
		return array(
			'author' => array(self::BELONGS_TO, 'User', 'author_id'),
			'categories'=>array(self::MANY_MANY, 'Category',
				'{{post_category}}(post_id, category_id)'),  //{{}}でtablePrefixを適用する
			//categories'=>array(self::MANY_MANY, 'Category', // ガイドの例
			//    'tbl_post_category(post_id, category_id)'),
			//'postCategories' => array(self::HAS_MANY, 'PostCategory', 'post_id'), //Gii で生成
		);
	}
}

/webapp/protected/models/User.php (の一部)

<?php
/**
 * This is the model class for table "{{user}}".
 *
 * The followings are the available columns in table '{{user}}':
 * @property integer $id
 * @property string $username
 * @property string $password
 * @property string $email
 *
 * The followings are the available model relations:
 * @property Post[] $posts
 * @property Profile $profile
 */
class User extends CActiveRecord
{
	public function relations()
	{
		return array(
			'posts'=>array(self::HAS_MANY, 'Post', 'author_id'),
			'profile'=>array(self::HAS_ONE, 'Profile', 'owner_id'),
		);
	}
}