Posts tagged assosiation
CakePHP アソシエーションのまとめ(4)
0まとめ(1) では1対1のアソシエーション hasOne でしたが、
今回は1対多のアソシエーション hasMany です。
例えば、一人のユーザに複数のコメント投稿があるような場合です。
データベースは
CREATE TABLE users( id int unsigned auto_increment primary key, nickname varchar(30) NOT NULL, created datetime default NULL, modified datetime default NULL ); CREATE TABLE posts( id int unsigned auto_increment primary key, user_id int unsigned unique, comment text, created datetime default NULL, modified datetime default NULL );
のような場合、アソシエーションの定義は下記のようになります。
< ?php class User extends AppModel { var $name = 'User'; var $hasMany = array('Post' => array('className' => 'Post', 'conditions' => '', 'order' => '', 'foreignKey' => 'user_id', 'dependent' => true, 'exclusive' => false, 'finderQuery' => '' ) ); } ?>
これで、
$this->User->findById($id);
とすると下記のようにデータを取得できます。
Array ( [User] => Array ( [id] => 1 [nickname] => boze ) [Post] => Array ( [0] => Array ( [id] => 1 [user_id] => 1 [comment] => コメント1です ) [1] => Array ( [id] => 1 [user_id] => 1 [comment] => コメント2です ) .... ) );
また、hasOne などと同様に CakePHP の命名規約に従っていれば、foreignKey は指定しなくても大丈夫ですので、最低限
var $hasMany = array('Post');
でもアソシエーションを定義できます。
また、hasMany で指定する配列の意味は下記の通りです。
className
関連付けたいモデルのクラス名
conditions
hasMany で取得したいデータの条件を指定する。 SQL の条件文。
order
関連するモデルのデータの並び順。SQL の ORDER 句の指定方法。
Post.created DESC
テーブル名をカラム名の前に付けないと、User.created と区別できません。
limit
Cake が取り出す関連モデルのデータの最大数。
‘limit’ => 5 のように数字で指定。
foreignKey
関連しているモデルを指している外部キーの名前。
Cake の命名規約に従っている場合は省略可能。従っていない場合はここで指定する。
dependent
true に設定すると、モデルのデータの削除時に関連しているモデル側のデータも削除される。
exclusive
true に設定すると、関連しているすべてのオブジェクトが一つの SQL ステートメントで削除される。
finderQuery
アソシエーションを取り出すために、完全な SQL ステートメントを指定する。
CakePHP 日本語マニュアル
6.4. アソシエーション
CakePHP アソシエーションのまとめ(3)
1今回は belongsTo です。
CakePHP アソシエーションのまとめ(1) で hasOne をやりましたが、belongsTo はその逆です。
まとめ(1) で使用したテーブルで説明すると、Profile モデルにUser モデルを関連付けるのが belongsTo になります。
profile.php
<?php class Profile extends AppModel { var $name = 'Profile'; var $belongsTo = array('User' => array('className' => 'User', 'conditions' => '', 'order' => '', 'foreignKey' => 'user_id' ) ); } ?>
配列のそれぞれの意味は CakePHP アソシエーションのまとめ(2) に説明があります。
これで、
$this->profile->findById($id);
とかすると、Profile モデルの該当するID のデータ内容とそのProfile モデルの元の User モデルのデータが取得できます。
もちろん、CakePHP の命名規則に従っていれば、
profile.php
<?php class Profile extends AppModel { var $name = 'Profile'; var $belongsTo = array('User'); } ?>
でもいけます。
CakePHP アソシエーションのまとめ(2)
0アソシエーションのまとめ(1) で書いた
< ?php class User extends AppModel { var $name = 'User'; var $hasOne = array('Profile' => array('className' => 'Profile', 'conditions' => '', 'order' => '', 'dependent' => true, 'foreignKey' => 'user_id' ) ); } ?>
この部分の補足です。
それぞれの意味するところは
var $hasOne = array('関連先のモデル名'=> array('className' => '関連先のモデルのクラス名', 'conditions' => '関連を定義するSQL条件の一部', 'order' => '関連先のデータの並び順', 'dependent' => '関連先データの同時削除', 'foreignKey' => '関連先テーブル側の外部キー' ) );
conditions は条件を付けて関連付けるモデルのデータを制限するときに指定する。
dependent は関連元のデータが削除されたときに、一緒に関連先のデータも削除するかどうか。
関連先のモデルで関連元のモデルの主キーを定義しているカラム名です。
dependent などはかなり便利に使えそうですね。
アソシエーションのまとめ(1) に書いたように、 foreignKey は CakePHP の命名規則に従っていれば省略可能です。
CakePHP アソシエーションのまとめ(1)
1CakePHP のアソシエーションのまとめです。
タイトルに (1) とつけたので多分何回か続けます。
アソシエーションとはモデル間のつながりのことです。
例えば、下記のような2つのテーブルがあると
CREATE TABLE users( id int unsigned auto_increment primary key, nickname varchar(30) NOT NULL, created datetime default NULL, modified datetime default NULL ); CREATE TABLE profiles( id int unsigned auto_increment primary key, user_id int unsigned unique, blog_url varchar(256), hobby varchar(256), created datetime default NULL, modified datetime default NULL );
CakePHP では2つのモデルになります。
User モデルと Profile モデルです。
この2つのモデルは1対1の関係になります。
「一人のユーザは1つのプロファイルを持つ」とういことです。
この2つのモデルの関係を CakePHP に指示するには次のようになります。
< ?php class User extends AppModel { var $name = 'User'; var $hasOne = array('Profile' => array('className' => 'Profile', 'conditions' => '', 'order' => '', 'dependent' => true, 'foreignKey' => 'user_id' ) ); } ?>
これで、
$this->User->findById($id);
とすることにより、
Array ( [User] => Array ( [id] => 1 [nickname] => boze ) [Profile] => Array ( [id] => 1 [blog_url] => http://www.syuhari.jp/blog [hobby] => 読書 ) );
のようにUser モデルだけでなく、Profileモデルの情報も同時に取得することができます。
CakePHP の命名規則を守っていれば、
var $hasOne = array('Profile');
だけでもいけるようです。
※外部キーはモデル名+_id
CakePHP 日本語マニュアル
6.4. アソシエーション