2012年5月10日木曜日

Scaffoldingを使ってみる

前回でテーブルは作成したので、今回から(やっと)cakePHPで郵便番号検索の開発をしはじめてみる。ここからはモデルを作って、コントローラーを作って、ビューを作って…ってしていくのだろうけど、その前にScaffoldingがどういうのかやってみたかったから、今回ちょろちょろっと作成してみた。

Scaffoldingとは

CookBook2.x(英語版)にそこまで詳しくない程度に載ってます。…というより後で気づいたんだけど、書いてる内容はCookBook1.3(日本語版)と殆どかわらなかった。かいつまんで書くと、Scaffoldingアプリケーションを使用するとデータの編集や作成、削除などが簡単にできて作成当初役立つらしい。たしかに、ウェブページを作成する時って必ずといっていいほど最初にいくつかデータを入れてテストするもんね。むしろそうしないと作り始められないし。

ちなみにScaffoldは「足場」という意味で、開発者が最初に使うツールという位置づけなのだそうです。CookBook2.x英語版ではpretty coolやso coolとクールを連発してます。そして1.3の日本語版でも連発してます。

使い方

簡単過ぎてびっくり。

1.コントローラーを以下のように作成する

前回の作成でテーブル名をpostal_codesとしたので、コントローラ名は命名規則に沿うと「PostalCodesController」となる。
そしてクラスの中には$scaffoldのみを記載する。

[app/Controller/PostalCodesController.php]
<?php
   class PostalCodesController extends AppController {
       var $scaffold;
   }
?>
2.おしまい



おしまい?

あら、やだ、簡単。Scaffoldingではモデルを作る必要すらないらしい。
本当にこんなので使えるのかなって半信半疑でアクセスしてみて、またびっくり。
http://localhost/[cakephpFolder]/postal_codes/にアクセスすると・・・

タイトルの部分、「Postal Codes」ってわざわざアンダーバーの部分がスペースに変わってるんだね。cakePHPってそんな小細工もできるのかぁ。
ちなみに、フィールド名の部分をクリックすると昇順/降順でソートもできるし、リストの下の方はこんな感じにちゃんとページナビゲーションと発行したクエリのリストまでついてる。
(発行クエリのリストは、開発中ならどの作成ページにもつくらしいけど)

この「View」ってボタンを押すとこんな感じ。

新規作成と編集画面もなかなか見やすくなってる。

不思議だねぇ。まあ、今回はもうデータは全部入れちゃってるし、これを使う機会はないんだけど。でも、かなり関心した。cakePHPすごいねぇ。

Scaffoldingを使うにあたって

この機能は、あくまでも開発の初期に使用する前提で用意されており、できることは「全体の閲覧」「挿入」「編集」と基本的なことしかできない(当たり前か)。また、$scaffoldを使う場合、他のアクションを入れるとうまく機能しなくなったり、変な動作をしたりするみたい。

まあ、本当に最初の頃にデータを入れる時に使うのであれば全然問題ないよね。あとはせっかくだからカラムやインデックスの作成/編集/削除ができれば最高なんだけど…phpMyAdminみたいに。

(補足)joinテーブルでScaffoldingしてみる

なお、今回は一つのテーブルだけを使ってScaffoldingしたけど、joinテーブルもできるらしい(CookBook1.3日本語版ではなぜかそこの注意点の部分が抜けてる。2.0英語版も1.3英語版も書いてるのに)。郵便番号検索のとは関係ないけど、一応その仕方も調べてみたからまとめておく。

$hasManyと$belongsTo

cakePHPでは、この$hasMany$belongsToといった変数に情報を入力することでJoinを実装するらしい。
他にも方法はいろいろとあるけど、それは別の機会にじっくり調べるとして、今回はやり方だけざっくり書いておく。

2つのテーブルを作成

本当は今回作ったpostal_codesテーブルで作成したかったんだけど、既に12万件データが入ってるなかでjoinしようとしたら重すぎてダメだったんで(どうも、join先のテーブルで全件読み込もうとしちゃうらしい)、新たに簡単なテーブルを作成した。

#testsテーブルを作成
mysql> create table if not exists tests(
    -> id int(11) not null auto_increment ,
    -> title varchar(50) collate utf8_bin not null ,
    -> username varchar(30) collate utf8_bin not null ,
    -> primary key (id)
    -> )Engine=Myisam default character set utf8 collate utf8_bin;
Query OK, 0 rows affected (0.11 sec)

#test_commentsテーブルを作成
mysql> create table if not exists test_comments(
    ->  id int(11) not null auto_increment ,
    ->  created datetime not null ,
    ->  comment varchar(100) collate utf8_bin not null ,
    ->  test_id int(11) not null ,
    ->  primary key (id),
    ->  key test_id (test_id)
    -> )Engine=Myisam default character set utf8 collate utf8_bin;
Query OK, 0 rows affected (0.05 sec)

なお、test_commentsテーブルの「test_id」が、cakePHPの命名規約に沿った外部キーの書き方となる(joinするテーブル名の単数形_id)。
次にコントローラーとモデルを作成。joinをする場合、モデル作成は必須っぽい。

// app/Controller/TestsController.php
<?php
   class TestsController extends AppController {
         public $scaffold;
   }
?>

// app/Controller/TestCommentsController.php
<?php
   class TestCommentsController extends AppController {
         public $scaffold;
   }
?>

// app/Model/Test.php
<?php
   class Test extends AppModel{
         public $hasMany = array('TestComment');
   }
?>

// app/Model/TestComment.php
<?php
   class TestComment extends AppModel{
         public $belongsTo = array('Test');
   }
?>

これで準備完了。命名規約に沿ってつくれば、これだけで全部読み込んでくれる。
$belongsToは外部キーがあるテーブルに、$hasManyは参照されるテーブルに書けばいいらしい。
そして両方のモデルに、それぞれ上のように設定することでScaffoldingでjoinされた結果がでてくる。
(これはあくまでScaffoldingを使用する時の設定です)

あとは、testsまたはtests_commentにアクセスすればいいだけ。いくつか作成したのが下の画像になります。

変な名前は気にしないでください。
testsを開いたんだけど、「New Test Comment」「List Test Comment」ってボタンができてる。
Viewを開くとこんな感じ。

一方、test_contentsを開くとこんな具合に結合がされている。

なお、Titleの部分が表示されてるのは、命名規約でtitleまたはnameというフィールド名がリストタイトルとして認識される為。
Scaffoldingではそのリストタイトルだけが表示されるみたい。
この表示を変えたい場合、モデルのTest.phpに以下のように付け加える。

// app/Model/Test.php
<?php
   class Test extends AppModel{
         public $hasMany = array('TestComment');
         public $displayField = 'username';
   }
?>

すると、usernameのカラムが表示される。

テストだから変な名前なのはスルーしてください。


ついでだから、titleカラムを別の変な名前にしてリストタイトルとして認識できるカラムが存在しない状態にするとどうなるかも確かめてみた。

mysql> alter table tests change title testname varchar(50) collate utf8_bin not null;
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0

$displayFieldを消して再度アクセスしてみる。

なるほどー・・・主キーが表示されるのかあ。


まあ、でも最初に使うには便利そう。

本当は郵便番号検索のラベルでエントリしようと思ったんだけど、全然関係なくなってしまったので今回は単一でのエントリとしました。次回から本当に作成しだそ。

【参考リンク】
CookBook2.x(英語版)
CookBook1.3(日本語版)

0 件のコメント:

コメントを投稿