hasOne アソシエーション
hasOneアソシエーションはテーブル間で1つのレコードに対して他のテーブルに紐付くレコードが1つの場合にjoinする場合に使用します。
CakePHPのドキュメントにならってUserモデルとProfileモデルで例を。
本来ならば、テーブルに外部キーを設定し、整合性を担保させると思いますが、hasOneを使用するのに必須ではありません。
usersテーブル
CREATE TABLE IF NOT EXISTS `users` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `username` VARCHAR(255) NOT NULL, `password` CHAR(128) NULL, `status` TINYINT NULL, `created` DATETIME NULL, `modified` DATETIME NULL, PRIMARY KEY (`id`), UNIQUE INDEX `username_UNIQUE` (`username` ASC)) ENGINE = InnoDB
profilesテーブル
CREATE TABLE IF NOT EXISTS `lab`.`profiles` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `user_id` INT UNSIGNED NOT NULL, `first_name` VARCHAR(64) NULL, `last_name` VARCHAR(64) NULL, `bio` TEXT NULL, `created` DATETIME NULL, `modified` DATETIME NULL, PRIMARY KEY (`id`)) ENGINE = InnoDB
Userモデル
// app/Model/User.php
public $hasOne = array(
'Profile' => array(
// 'className' => 'Profile',
// 'foreignKey' => 'User_id',
// 'conditions' => array( 'Profile.status' => '1'),
// 'fields' =>
// 'order' => 'Profile.created DESC',
// 'dependent' => true
)
);
className hasOne先のモデル名
conditions JOINする条件
fields 取得するカラム
order 並べ替え
dependent trueの場合、親(User)側レコードが削除された場合に子(Profile)も削除される。(これは別記事にて)
実行SQL
SELECT `User`.`id`, `User`.`username`, `User`.`password`, `User`.`status`, `User`.`created`, `User`.`modified`, `Profile`.`id`, `Profile`.`user_id`, `Profile`.`first_name`, `Profile`.`last_name`, `Profile`.`bio`, `Profile`.`created`, `Profile`.`modified` FROM `users` AS `User` LEFT JOIN `profiles` AS `Profile` ON (`Profile`.`user_id` = `User`.`id`) WHERE 1 = 1
レコード数増に伴う性能改善
レコード数が増えていくと、joinするのに時間がかかっていきますので、インデックスを張って下さい。
4000行のhasOne(Left Join)でDB/Cake両方のキャッシュをOFF
インデックスなしの場合→平均13秒ほど
インデックスありの場合→50ミリ秒ほど
(って、秒数はマシンスペックによります。)
MySQLでの外部キーとインデックスの作成はこちらを参考にして下さい。hasOneの場合はuniqueオプションを使用して下さい。
外部キー(foreign key)を作成するとインデックスもついてくる | MySQL
Models > Associations > hasOne
関連記事
-
-
RSSフィードの取得
コンロトーラ public function getrssfeed() { try { $newsItems = $this->Rss->read( 'http://
-
-
checkボックスを実装
selectボックスに引き続いてcheckボックスの実装方法をおさらいしてみます。 コードは、CakePHP 2と1.3両方で実装可能です。デモ モデルは、こちらも以下 CREATE TA
-
-
Markdown Plugin
「Markdown CakePHP Plugin」は、MarkDown書式をレンダリングしてくれるビューヘルパーです。MarkDownについて勉強しているうちに出会ったので試し打ちです。 ダウンロー
-
-
SQLクエリーをログに出力する
SQLのクエリーをデバッグするには、Debug Kitを使用すればできますが、デバッグログと一緒に出したいのでやり方を調査してみました。 別々のログやビューでみるのもいいですが、秒単位で実行される処
-
-
ログインに追加の条件を付与する「scope」
ユーザ登録では、仮登録処理(status=1)から送付したメール内のリンクをクリックしてもらい本登録(status=0)を行ってもらう実装をしました。仮登録の状態ではログインできないように実装するには
-
-
selectボックスを実装
今まで、selectボックスのgroupを作成するのにSet::Combineを使用していましたが、意外と簡単にできることに気付いてしまったので、ご紹介。(自分だけ知らなかったことに気付いた と言った
-
-
ネストしたリストを出力「nestedList」
DBやJSONからデータを取得して、そのデータをもとにメニュー表示などネストしたリストを出力させたい場合に「nestedList」が便利です。 ヘルパーに渡すデータは連想配列である必要があります。(
-
-
パス定数と変更方法やURLの取得
CakePHPは基本的にはディレクトリそのまま配置することで構築が可能ではありますが、設定パスを変更することでセキュリティに考慮した構成にすることや運用性をもたせたものにすることが可能になります。
-
-
Jsヘルパーを使用してAjax更新
更新処理でページ遷移を伴う場合、ページ全体をレスポンスするのに対して、Ajax処理ではページの一部のレスポンスが可能となるためサーバからの通信量を抑えることが可能となります。デモ head
-
-
Blowfishを使用してハッシュ化する
使用方法 Blowfishを採用してハッシュ化を行う場合、Securityクラスのhashメソッドを呼び出します。第2引数に'blowfish'を指定し、第3引数を指定しないもしくはfalseにしま


Comment
http://t.co/cbhroBOPba CakePHP 2.4 - hasOneアソシエーション ブログ投稿