モデルのqueryメソッドでfind、findAllと同等の返り値を得る方法
常識かもしれませんが、明言されている記事が見つからなかったのでエントリー。
動作確認バージョンは毎度のBeta 1.2.0.6311です。
queryとfind、findAllでの返り値の違い
例えばfindAllとqueryのそれぞれを使って全件取得した結果の違いを見比べてみます。(DBMSはMySQLを使用)
まずfindAllを使う場合。
$this->User->findAll();
の結果は
Array ( [0] => Array ( [User] => Array ( [id] => 1 [username] => aaa [password] => xxx ) ) [1] => Array ( [User] => Array ( [id] => 2 [username] => bbb [password] => yyy ) ) )
となります。
次にqueryを使った場合。
$this->User->query('select * from users');
の結果は
Array ( [0] => Array ( [users] => Array ( [id] => 1 [username] => aaa [password] => xxx ) ) [1] => Array ( [users] => Array ( [id] => 2 [username] => bbb [password] => yyy ) ) )
となります。
両者の違いは連想配列のkeyが'User'か'users'で異なる部分です。
このままでも使えることは使えますが、使用する側(コントローラやビュー)で配列のkeyが'User'と'users'で混在するのはシステムで統一感が無く、少し気持ち悪いです。
そこで次の方法を使えば、queryメソッドの場合も配列のkeyを'User'にすることが出来ます。
findAllと同じ返り値を得る方法
以下のようにテーブルに別名を付ける、その別名が配列のkeyとなります。
$this->User->query('select * from users as User');
とすると、
Array ( [0] => Array ( [User] => Array ( [id] => 1 [username] => aaa [password] => xxx ) ) [1] => Array ( [User] => Array ( [id] => 2 [username] => bbb [password] => yyy ) ) )
の結果が返ってきます。
結合させても大丈夫
結合させるテーブルにも別名をつけておくとアソシエーションを使った場合と同等の返り値を得ることが出来ます。
$this->User->query('select * from users as User left join posts as Post on Post.user_id = User.id');
の結果は
Array ( [0] => Array ( [User] => Array ( [id] => 1 [username] => aaa [password] => xxx ) [Post] => Array ( [id] => 1 [user_id] => 1 [title] => title1 [body] => hogehoge ) ) [1] => Array ( [User] => Array ( [id] => 2 [username] => bbb [password] => yyy ) [Post] => Array ( [id] => 2 [user_id] => 2 [title] => title2 [body] => hogehoge ) ) )
となります。
ちなみにPostgreSQLでは
少し試した感じではMySQLほど簡単には出来ないようでした。
PostgreSQLでqueryメソッドを使った場合、
$this->User->query('select * from users');
の結果は
Array ( [0] => Array ( [0] => Array ( [id] => 1 [username] => aaa [password] => xxx ) ) [1] => Array ( [0] => Array ( [id] => 2 [username] => bbb [password] => yyy ) ) )
と配列のkeyに'users'すら入りません。
次にMySQLではうまくいったテーブル名の別名をつけて、
$this->User->query('select * from users as "User"');
としても結果は変わらず。
色々試した結果、
$this->User->query('select id as "User__id", username as "User__username", password as "User__password" FROM users')
という風にフィールド名の別名として
keyにしたい文字 + __(アンダーバー2つ) + 列名
をセットすると、
Array ( [0] => Array ( [User] => Array ( [id] => 1 [username] => aaa [password] => xxx ) ) [1] => Array ( [User] => Array ( [id] => 2 [username] => bbb [password] => yyy ) ) )
という期待する値が返ってきました。
取得したいフィールド全てに別名を付けていかないと駄目なようです。