Posts tagged SQL
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 アソシエーションのまとめ(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デバッグモードのメモ
/app/config/core.php の52行目に
define('DEBUG', 0);
と定義されているのがデバッグモード
この値を変更することにより、本番環境、開発環境と切り替えることができる。
DEBUG の値は
0: プロダクションモード。エラーは出力されず、デバッグメッセージも表示されません。
1: 開発モード。 Warnings とエラー、デバッグメッセージを表示します。
2: 開発モード。実行されたSQL 文が表示されます。
3: 開発モード。2に加えて、現在のオブジェクト(通常はコントローラ)のフルダンプも表示されます。
DEBUG=1 で開発を行い、データ取得などの挙動が考えているのと違うときに、
DEBUG=2 にするという感じでやっています。
あまり、 DEBUG=3 を使用していないなあ。コントローラのダンプなので量が多すぎてかえって見づらいので、
debug($hoge);
などで必要なときに個別にダンプを出してしまいます。
もちろん本番環境では DEBUG=0 です。
CakePHP SQL を書いて実行する方法
1CakePHP ではSQL を書かなくてもだいたいなんでもできるのですが、
ちょこっとSQLを書いて実行したいことがあり調べたメモです。
/cake/libs/model/model_php5.php
を眺めていると findBySqlメソッドがありました。
引数はSQLを文字列で受け取ります。
これだ!っと思ったらただ単に
function findBySql($sql) {
return $this->query($sql);
}
となっている。。。
queryメソッドにSQLを投げればいいんですね。
$sql = "SELECT NOW()";
$foo = $this->HogeModel->query($sql);
CakePHP 実行したSQL を表示する方法
1開発中に実行されたSQLを表示したいことは多いと思います。
/app/config/core.php
の52行目あたりにある
define('DEBUG', 1);
を
define('DEBUG', 2);
と、デバッグレベルを2以上にするとブラウザの一番下にSQLが表示されます。
デバッグレベル3にすると「Controller dump」と表示され
そのときのコントローラの print_r と実行されたSQLが表示されます。
デバッグレベル2だと実行されたSQLのみ表示されます。
開発時には重宝しそうです。