前回 は、rhaco アプリケーションの基本となるFlowの仕組みについて解説しました。今回は、アプリケーションに頻出する一連の動作をライブラリが実現する Views(汎用ビュー)という機能について解説していきます。
Viewsについて
ウェブアプリケーションの開発において、データの登録・一覧・変更・削除(CRUD)といった動作は、ある程度共通化できることが多いです。そのため、( 特に)Ruby on Rails以降のフレームワークでは scaffolding と呼ばれる、アプリケーションの土台をジェネレートする機能が備わっていることもよくあります。
rhacoでは、これらの動作をひな形のようにしてライブラリで実現しています。簡単に言うと「どのモデルを用いて、どの動作するのか」を明示しさえすれば、CRUDを実現できるようになります。
これまで何度か使用しているセットアップアプリケーション(setup.php)のDB管理機能もこのViewsを用いて実現されています。
Viewsの持つ機能
Viewsを使うと、データベースに対して次のような機能が1つのメソッドで実現できるようになります。
作成(確認画面あり/なし)
更新(確認画面あり/なし)
削除
一覧(ページャ付き)
一覧機能の実装
さて、それでは前回 Flowを用いて実装した一覧画面を、Viewsを使ったものに書き換えてみましょう。
Views で一覧画面を実装するには、Views::read メソッドを使います。
views.php
<? php
require './__init__.php' ;
Rhaco :: import ( 'generic.Views' );
Rhaco :: import ( 'model.Todo' );
$views = new Views ();
$views -> read ( new Todo ());
$views -> write ( 'list.html' );
テンプレートは前回 作成したものを表示しています。
どうでしょう、幾分か簡単に書けるようになりましたね。リストだけではそれほど恩恵がわかりにくいかと思いますので、次はTodoを追加する機能を実装していきましょう。
データの登録処理
先に述べたように、Viewsを使うとCRUDがメソッド一つで実現できます。
まずは、データの登録の機能を作ってみます。データの登録は Views::create メソッドを使います。
views_create.php
<? php
require './__init__.php' ;
Rhaco :: import ( 'generic.Views' );
Rhaco :: import ( 'model.Todo' );
$views = new Views ();
$views -> create ( new Todo (), Rhaco :: url ())-> write ();
これだけで、データの登録機能については実装完了です。createの第二引数にはViewsへfilterを与えることができますが、ここでの説明は割愛します。デフォルトでは、データの作成後にリダイレクトする先のURLを与えることができるようになっています。
早速、 http://localhost/kaeru/views_create.php にアクセスしてみると、簡単なフォームが表示されます。
これは、rhacoが持っている簡易的なフォームを仮に使用することで、テンプレートを作成することなくフォームを実現できます。全体のデザインが決まっていない場合など、一時的なテストに使うのに便利です。
継承可能なテンプレート
rhacoでは、テンプレートに「継承(extends) 」という機能があります。PHPのクラスを継承するのと同様にして、ベースとなるテンプレートを継承することで、内容を変更したい部分だけを記述するといったことが可能になります。
それでは、作成したテンプレート(list.html)を継承に対応させてみましょう。継承先のテンプレートで書き換えたい部分を <rt:block> タグで囲います。
resources/template/list.html(変更点のみ)
< body >
< h1 > todo manager </ h1 >
< rt:block name = "content" >
</ rt:block >
</ body >
次にテンプレートを作成しますが、Viewsの規則にしたがったファイル名にすることで、コードに変更を加えずにテンプレートを切り替えることができます。
createに対応するフォームのテンプレートは、「 resources/template/generic/モデル名 _form.html」となります。
resources/template/generic/todo_form.html
< rt:extends href = "../list.html" />
< rt:block name = "content" >
< form action = "{$rhaco.uri()}" method = "post" >
< dl >
< rt:loop param = "{$object.models('views','form_display')}" var = "column" >
< rt:if param = "{$column.isSerial()}" >
{$viewutil.columnString($object,$column)}
< rt:else />
< dt > {$object.label($column)} </ dt >
< dt > {$viewutil.columnString($object,$column,true,true,'views')} </ dt >
</ rt:if >
</ rt:loop >
</ dl >
< input type = "submit" name = "save_create" value = "{$generic_button}" />
</ form >
</ rt:block >
このテンプレートでは、list.htmlを継承して、<rt:block>の“ content” の部分のみを置き換えるコードです。テンプレートのコード自体は、rhaco本体に含まれるものを多少シンプルにしただけです[1] 。
これを表示すると、list.htmlの“ content” 部分のみが置き換えられていることがわかります。
入力エラーを表示する
現在までのコードでは、subjectが空のままでtodoが登録されてしまいます。このままだと、何のことかまったくわからないTODO管理アプリになってしまうので、対策してみます。
rhacoでは、モデルに対してverifyが自動的に行われます。モデル定義はすべて setup/project.xml で行うということは第3回 で説明したとおりです。setup/project.xml のsubjectカラムにrequire属性を追加してみます。
setup/project.xml(抜粋/変更前)
< column name = "subject" />
↓
setup/project.xml(抜粋/変更後)
< column name = "subject" require = "true" />
project.xmlの変更を適用するには、再びsetup.phpにアクセスして、ページ下部の[setting]をクリックします。このとき、設定を変更する必要はありません。
これで、subjectが必須項目になりました。ためしに、さきほど作成したフォームを空のまま[create]すると、再びフォームに戻されるようになります。しかし、これでは何がエラーなのかわかりにくいですね。
次にエラーを表示させてみましょう。モデルで発生したエラーは、rhacoによって疑似的に例外がthrowされています。これは、PHP4でも動作するように、PHP5の例外機能は使用していません。
resources/template/generic/todo_form.html の <rt:block name="content"> のすぐ下に <rt:invalid /> と記述します。
この状態で、再びフォームを空のまま[create]すると、「 subject is required.」と表示されることが確認できます。
まとめ
今回はViews(汎用ビュー)機能を紹介しました。紹介したread、createメソッドのほかにdetail、update、confirmedCreate、confirmedUpdateといったメソッドも実装されています。引数については、rhaco-users.jp のドキュメントAPI などで確認できるので、ぜひ試してみてください。
次回は、URL構造を奇麗にする Urls を紹介する予定です。