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 を書いて実行する方法

1

CakePHP では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のみ表示されます。

開発時には重宝しそうです。

Go to Top