cakephp Schemaを使って初期データも突っ込む方法

 2009/10/18

cakephpではSchema機能を使ってテーブルを作成することが出来る。 で、ついでにマスター系データもまとめて登録する方法が【CakePHP】お手軽便利なCakeSchemaに載っている。 ただ載っている方法には若干問題がある。

  • そもそもcakephpでは、テーブルを使わないモデルでは$useTable=falseに設定しないといけなくて、それ以外の場合は、モデルへのアクセス時にテーブルが存在しないとエラーが発生する。
  • 従って、初期データを保存するためのモデルがアソシエーションが設定されているモデルだと、関連モデルのテーブルがまだ作成されていない場合にアクセスすると、その時点でエラーになってしまう。作成する順番だけを変えれば良いケースもあるだろうけど、相互参照しているようなモデルでは無理。
  • つまり、アソシエーションがある場合は先にテーブルを生成しなければならず、schema.phpのafterメソッドで、都度データを入れることはできないような気がする。(unBindModelとかしてみたけど、そもそもモデルのロードで先にエラーになるので、そもそもダメ)

ということで僕なりにアレンジしたのが以下の方法。

schema.phpのafterメソッド

function after($event = array()) {

    $model_names = array();
    $prop = get_class_vars(get_class($this));
    foreach($prop as $key => $value)
    {
        $s = Inflector::classify($key);
        if (!($s == "Name" || $s == "File" || $s == "Path" || $s == "Log" || $s == "Connection" || $s == "Table"))
        {
            $model_names[] = $s;
        }
    }

    if(!empty($event['create'])){
        if(!isset($this->InitialValues)){
            require_once($this->path.DS.'initial_values.php');
            $this->InitialValues = new InitialValues();
        }
        $modelname = Inflector::classify($event['create']);

        if($modelname == $model_names[count($model_names)-1])
        {
            foreach($model_names as $target_modelname)
            {
                $this->InitialValues->set($target_modelname);
            }
        }
    }
}

肝は、全部のデータを最後のテーブルの作成完了後に作る、というだけ。 NameとかFileとか除外しているところはin_arrayで除外した方がいいけど、まぁいいか。

 2009/10/18

著作

寄稿

Latest post: