例えば Scale と, ScaleMin という2つのモデルは作成すべきでない。ScaleMin というモデル名に、Scale モデルの名称が包含されてしまうためである。
AkAssociatedActiveRecord.php(384L近辺)に以下のような記述がある。
「}elseif(preg_match('/^_('.join('|',$associated_ids).')_(.+)/',$column, $match)){」
上記コードはDB検索結果を、モデルの各オブジェクトに適切に変数を振り分けるための処理を行っているコードである。
Scale, ScaleMin という二つのモデルを例にすると次のようになる。SQLは正しく発行できているので、DBからは正しいデータが出力されている。しかし「ScaleMin」モデル用の変数を上記コードの箇所で「Scale」モデルに振り分けてしまう。
「Scale」モデル用の変数は正しく振り分けられるので、「Scale」モデルには「Scale」モデル用の変数と、「ScaleMin」モデル用の変数が両方割り当てられてしまう。
「"・・・php.exe" script\generate scaffold Scale_min --sintags」
「・・・\app\models\scale_min.php」 に 「ScaleMin」 というモデルが生成され、ScaleMin モデル は 「scale_mins」 というDBテーブルに対応付けられる事になる。
ScaleMin モデル が対応するテーブルを scale_mins ではない他のDBテーブル(ここでは scales とする)に対応付けるには、どうすれば良いのかソースを調べてみた。
AkActiveRecord クラスに 「$table_name」 というクラス変数が定義されているので、前記 $table_name に対応付けたいテーブル名 「scales」 を設定すれば良い。
以下のように、ScaleMin モデル内に「$table_name」を定義しておくと良いと思う。
class ScaleMin extends ActiveRecord
{
var $table_name = 'scales';
}
なぜこのような処理をする必要があったかと言うと、「ScaleMin」、「ScaleMax」という二つのモデルを作成するが、前記2つのモデルを対応付けるDBテーブルの内容は共通の内容であったためである。
「ScaleMin」、「ScaleMax」モデル毎に個々のDBテーブルを作成すれば上記のような処理をする必要はないがスマートではないので、モデルとDBテーブルの対応付けを変更する方法を知っていると何かと役に立つと思う。
最終的にはコードを以下のように記述した。(要点のみ記述)
(1)Scale関連モデル
class Scale extends ActiveRecord
{
var $table_name = 'scales';
}
class ScaleMin extends Scale
{
}
class ScaleMax extends Scale
{
}
(2)ScaleモデルのアソシエーションIDを持つモデル(ここでは「Image」)のテーブル構造
$this->createTable('images', "id, scale_min_id, scale_max_id ");
(3)その他
あと has_many, belong_to 変数の設定や検索時の include オプションなどは通常通り記述すれば良い。
コメントに記述してある通りの動作となった方が、ソースがすっきりと書けるので、次のコードを変更して、以下のコメント通りの動作となるようにした。
(1)変更箇所
date_helper.php(348L近辺) の _select_html 関数
(2)変更内容
・変更前: ($discard_type ? '' : $type).'"'.
・変更後: ($discard_type ? '' : "[$type]").'"'.
------- 以下は date_helper.php に記述されているコメント -------
* * :prefix - overwrites the default prefix of "date" used for the select names. So specifying "birthday" would give
* birthday[month] instead of date[month] if passed to the select_month method.
* * :include_blank - set to true if it should be possible to set an empty date.
* * :discard_type - set to true if you want to discard the type part of the select name. If set to true, the select_month
* method would use simply "date" (which can be overwritten using :prefix) instead of "date[month]".
Bの status が 0 である A のレコードを検索する場合は以下のようなコードを記述すれば良い。
以下コードのポイントは以下の2点である。
(1)$belong_to
Bモデルに対して include_conditions_when_included(true) と conditions(status=0)を$belong_to に設定する。
なお、include_conditions_when_included に false を設定すると、conditions は無視される。
(2)includeオプション
Bモデルに対して conditions を設定する。
−−−−−−− コード −−−−−−−−−
// コントローラなどに記述するコード
$this->a->find();
// モデルに記述するコード
class A extends ActiveRecord
{
var $belongs_to = array( 'B =>
array('include_conditions_when_included' => true,
'conditions' => 'status=0')
);
function find()
{
$option = array('include' => array('B' => array('conditions'));
return parent::find('all', $option);
}
}


