http://book.cakephp.org/2.0/ja/models/associations-linking-models-together.html
http://blog.ecworks.jp/archives/268
http://qiita.com/kazu56/items/eaaa0c2d7294a28ac21c
http://qiita.com/moriyant/items/b57ee4fc45af2fc03194
hasとbelongが、すぐどっちがどっちかわからなくなる。
「持っている」とかアバウトな言葉じゃなくてテーブル定義で教えてくれ。
結論
- hasMany
- 相手テーブルに、自分テーブル.idへの外部キーがある。
- hasOne
- hasManyだけど外部キーがUNIQUE。
- belongsTo
- 自分のテーブルに、相手テーブル.idの外部キーがある。
- hasAndBelongsToMany
- 中間テーブルでくっついてるやつ。
hasMany
ユーザは複数の趣味を持っている。任意入力。
class User{
$hasMany = [
'Hobby'=>[
'className' => 'Hobby',
],
];
}
特に趣味に関する項目はない。
id
user_id ← users.idに外部キー
name
趣味をスペース区切りとかで複数入力してもらい、それをそのまま保存するタイプのユーザ登録。
よくある構造のテーブルです。
hasOne
ユーザはひとつのプロフィールを持っている。
class User{
$hasOne = [
'Profile'=>[
'className' => 'Profile',
],
];
}
プロフィールに関する項目はない。
id
user_id ← users.idに外部キー、かつUNIQUE制約
family_name
first_name
この構造は公式の例なのですが、でもこういう場合普通はusersテーブルに個人情報入れるよな。
hasOneを使うということはつまりテーブルの垂直分割なので、あまり使う必要性が感じられない。
belongsTo
ユーザは職業IDを持っている。
class User{
$belongsTo = [
'Employment'=>[
'className' => 'Employment',
],
];
}
id
employment_id ← employments.idに外部キー
id
name
employmentsテーブルには「学生」「会社員」「無職」などのデータが入っていて、ユーザ登録時にその項目を選択してIDを登録するというよくある形態。
hasAndBelongsToMany
ユーザは複数の趣味を持っている。選択式。
class User{
$hasAndBelongsToMany = [
'Hobby'=>[
'className' => 'Hobby',
'with' => 'UserHobby',
'foreignKey' => 'hobby_id',
'associationForeignKey' => 'user_id',
],
];
}
特に趣味に関する項目はない。
id
name
id
user_id ← users.idに外部キー
hobby_id ← hobbies.idに外部キー
hasManyの趣味は直接入力でしたが、こちらは予め項目が表示されており、その中からチェックボックスで複数選択するタイプの登録フォーム。
UserとHobbyにUserHobbyへのhasMany、UserHobbyからUserとHobbyへのbelongsToを書けばだいたい同じ意味になると思うけど、めんどうなので一気に書けるとかそういうかんじですかね。
その他
リレーションがあるだけひたすら書いておくだけで、findすると勝手に拾ってきてくれて便利なのですが、SQLの発行数がえらいことになります。
辿る深さはrecursiveで制御できますが、何故か特定の先だけ制御する方法がありません。
A→B→C→D
↓
E→F→G
↓
H→I
↓
J
なんてテーブルがあったとして、Dが欲しいんだと$this->A->recursive = 3
と設定するとSQLが何十個も発行されます。
や、Bの先だけ欲しいんだと$this->A->B->recursive=2;$this->A->E->recursive=-1;
とか書いても、どうも効かないみたいです。
そういう記事が全く見当たらないんだけどできないんじゃろうか。
あとrecursive深くするとA→B→A→Bなんてのも辿るみたいなんだけどこれは必要なのか?