2012年7月25日水曜日

モデル間のリレショーンをためしてみた(FuelPHP)

Orm(Object Relation Mapping)の利点はリレーションを意識したモデル操作ができる。
と本に書いてたんで試してみました。

試してみたのはユーザとグループを関連付けるだけ。
必要なテーブルはユーザ(users)とグループ(groups)、この2つを関連付ける中間テーブル(users_groups)の3つです。

まずは oil コマンドでモデルを作ります。
$ oil g model users name:varchar[50] login_id:varchar[50] password:string
$ oil g model groups name:varchar[50]
$ oil refine migrate

fuel/app/classes/model に user.php と group.php が作られ、
oil refine migrate を実行するとテーブルも作られると思います。

次に中間テーブル(users_groups)
CREATE users_groups (
    user_id int(11) NOT NULL,
    group_id int(11) NOT NULL,
    PRIMARY KEY (user_id, group_id)
);

これで準備はOK。

やりたいことはユーザを登録するときに合わせてグループの関連付けも登録、削除するときは関連付けも一緒に削除。

まず、モデルファイル(user.php)に以下を追加します。
protected static $_many_many = array(
    'groups' => array(
        'key_from' => 'id',
        'key_through_form' => 'user_id',
        'table_through' => 'users_groups',
        'key_through_to' => 'group_id',
        'model_to' => 'Model_Group',
        'key_to' => 'id',
        'cascade_save' => true,
        'cascade_delete' => true,
    ),
);

こんなかんじでリレーションの設定を行います。
項目の詳細はマニュアルを見るのが一番かなと。(自分もまだよくわかってないし)
http://docs.fuelphp.com/packages/orm/relations/many_many.html

次に実際にコントローラから登録をする処理です。
public function action_create()
{
    // グループ情報を取得
    $groups = Model_Group::find()->get();

    if (Input::method() == 'POST')
    {
        // Authインスタンス
        $auth = Auth::instance();

        // ユーザ
        $user = Model_User::forge();
        $user->name = Input::post('name');
        $user->login_id = Input::post('login_id');
        $user->password = $auth->hash_password(Input::post('password'));

        // 関連付け
        if (Input::post('group_id'))
        {
            for (Input::post('group_id') as $group_id)
            {
                $group = Model_Group::find($group_id);
                if ($group)
                {
                    $user->groups[] = $group;
                }
            }
        }

        // 登録
        $user->save();
    }
}

ざっくり書きましたがこんなかんじになります。
グループの関連は複数を相当して書いてみました。
これを動かすと users と users_groups のテーブルに値が書き込まれるはずです。

またこれでユーザを削除する場合も $user->delete() で users_groups も削除されますし、データを取得する場合も $user->find($id) だけで users_groups の情報も取得してきます。

いろいろ関連ついてくると複雑になりそうなんで簡単ものから徐々に。

※書籍には「中間テーブルに対応するモデルを作成することで、_many_manyを使わず_has_manyを使う」と書いていたんですが・・・
なんかうまくいかなかったです。時間見つけたまたトライしてみます。



0 件のコメント:

コメントを投稿