リレーショナルアクティブレコードを使ってみる

yii1.1.8 リリースとともにガイドのリレーショナルアクティブレコードページが更新され、英語ガイドページとの同期が取れました。これまで、日本語ガイドと英語ガイドを行き来して面倒だったんです。翻訳の皆さんありがとうございます。

リレーション宣言で特にわからないのが「ForeignKey」の書き方でした。以下は試行錯誤してやっと解決したときのメモです*1

  'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...付加オプション)

HAS_ONE

ガイド例「User」「Profile」の関係です。次はガイドのコードにコメントを付与したものです。

<?php
class User extends CActiveRecord
{
    public function relations()
    {
        return array(

            'profile'=>array(self::HAS_ONE, 'Profile', 'owner_id'),
            //VarName        RelationType    ClassName  ForeignKey

            //VarName:    Userクラスに拡張するフィールド名
            //ClassName:  拡張するフィールドに対応するCActiveRecordクラス
            //ForeignKey: こちら(tbl_user)のPKに対応する相手カラムを指定する 
            //            つまり tbl_profile.owner_id であり Profile->owner_id
        );
    }
}

HAS_MANY

ガイド例「User」「Post」の関係です。

<?php
class User extends CActiveRecord
{
    public function relations()
    {
        return array(

            'posts'=>array(self::HAS_MANY, 'Post', 'author_id'),
            //VarName      RelationType    ClassName  ForeignKey

            //VarName:    Userクラスに拡張するフィールド名
            //ClassName:  拡張するフィールドに対応するCActiveRecordクラス
            //ForeignKey: こちら(tbl_user)のPKに対応する相手のカラムを指定する
            //            つまり tbl_post.author_id であり Post->author_id
        );
    }
}

BELONGS_TO

ガイド例「Post」「User」の関係です。

<?php
class Post extends CActiveRecord
{
    public function relations()
    {
        return array(
            'author'=>array(self::BELONGS_TO, 'User', 'author_id'),
            //VarName       RelationType      ClassName  ForeignKey

            //VarName:    Postクラスに拡張するフィールド名
            //ClassName:  Postクラスに拡張するフィールドに対応するCActiveRecordクラス
            //ForeignKey: 相手(tbl_user)のPKに対応するこちらのカラム名を指定する
            //            つまり tbl_post.author_id であり Post->author_id
        );
    }
}

MANY_MANY

ガイド例「Post」「Category」と中間のテーブル「tbl_post_category」の関係です。

<?php
class Post extends CActiveRecord
{
    public function relations()
    {
        return array(
            'categories'=>array(self::MANY_MANY, 'Category', 'tbl_post_category(post_id, category_id)'),
            //VarName           RelationType      ClassName   ForeignKey

            //VarName:    Postクラスに拡張するフィールド名
            //ClassName:  拡張するフィールドに対応するCActiveRecordクラス
            //ForeignKey: 中間テーブル名(カラムこちら, カラムあっち)
            //            - tablePrefixを効かせるなら{{}}でかこむ
            //            - カラムこちら  :こちら(tbl_post)のPKに対応する中間テーブルのカラム名
            //            - カラムあっち  :あっち(tbl_category)のPKに対応する中間テーブルのカラム名
        );
    }
}

*1:更新前の日本語ガイドはER図とコードにズレがありました。さらにMyISAMを使うときは外部キーが使えないから、外部キーを模したコメントを付与する必要があるとかなんとか...で試行錯誤を繰り返しました。2ヶ月以上前のことですが