virtualField機能使ってみた
shin1x1さんがtwitterで「ver1.3にこんな機能がある」とtwitterで呟かれていたのをみて、実際に使ってみました。
virtualField機能で、できること*1
まずは、作成したMemberモデルに、元記事を参考に、$virtualFieldを設定して見ます*2。
app/model/members.php
var $virtualFields = array( 'name' => 'CONCAT(Member.first_name, " ", Member.family_name)' );
そして、bakeで作ったindex(members一覧)にアクセスすると、こんなSQLが出力されていました。
SELECT `Member`.`id`, `Member`.`first_name`, `Member`.`family_name`, `Member`.`created`, `Member`.`modified`, (CONCAT(`Member`.`first_name`, " ", `Member`.`family_name`)) AS `Member__name` FROM `members` AS `Member` WHERE 1 = 1 LIMIT 20
不覚なことに、私、SQLはあまり複雑な使い方はしてこなかったため、「CONCAT」という表現にピンときてませんでした。
これ、SQLの文字列関数です(゚ロ゚;)
つまり、virtualFieldを使うと、
SELECTのフィールド指定部分に、いろいろ自由にセットできるということ?
試しに、違う関数を入れてみる。
var $virtualFields = array( 'name' => 'CONCAT(Member.family_name, " ", Member.first_name)', 'date' => 'DATE(Member.created)' // 追加 );
そして、再度index()にアクセス。
SELECT `Member`.`id`, `Member`.`first_name`, `Member`.`family_name`, `Member`.`created`, `Member`.`modified`, (CONCAT(`Member`.`family_name`, " ", `Member`.`first_name`)) AS `Member__name`, (DATE(`Member`.`created`)) AS `Member__date` FROM `members` AS `Member` WHERE 1 = 1 LIMIT 20
結果をvar_dumpで出力してみる。
array(1) {
[0]=> array(1)
{ ["Member"]=> array(7)
{ ["id"]=> string(1) "1"
(中略)
["name"]=> string(13) "坂東 太郎"
["date"]=> string(10) "2010-01-20"
おおー ^^
AS `Member__name`
とダブルアンダースコアで参照されてたので変数名心配だったんですが、気にしなくてOK。
さらに試しに、membersテーブルに、「money(所持金)」なんてカラムを追加して、数値計算とかしてみる。
mysql> ALTER TABLE members ADD COLUMN money INT(11) NOT NULL default '0'; Query OK, 1 row affected (0.05 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> quit Bye [cake@cake app]$ cd ../ [cake@cake cakephp-13b]$ vi app/views/members/index.ctp (以下略、indexとadd,editにnameとmoneyの表示追加)
一覧に、nameとmoneyがでるようになったところで、データ追加。
そして、同じfamily_nameのメンバーのmoneyを合算して一覧表示するアクションを作成。
app/controller/members_controller.php
function grouped_list() { $this->Member->virtualFields['money_sum'] = 'SUM(Member.Money)'; $list = $this->Member->find('all', array( 'group' => 'Member.family_name', ) ); $this->set('members', $list); }
できました! (^^)
フィールドに自由にセットできるので、使い方次第でいろんなことが出来そうです。