CGIKit、TapKit を利用した Web アプリケーションの作成
初稿:2005-02-15
著者:喜多川 豪 編集:かずひこ
CGIKit、TapKit を利用した Web アプリケーションの作成
1. はじめに
Ruby で CGI を作成した事がある方は判るかと思いますが、Ruby には cgi.rb というライブラリが標準で利用する事が出来ます。
cgi.rb でコードの再利用やテンプレートとロジックの分離等を行うためには自前でライブラリを書いたりする必要があります。
また、バックエンドにデータベースを利用する場合、なるべくロジックからはデータベースを意識しないようなコードを書きたくなります。
これらの問題を解消する手段として、本記事では Web アプリケーションフレームワークの CGIKit、O/R マッピングツールの TapKit を利用した Web アプリケーションの作成方法を説明します。
2. CGIKit とは?
CGIKit は Ruby で書かれた Web アプリケーションフレームワークです。
CGIKit による Web アプリケーションは、
- テンプレート (.html)
- バインディング (.ckd)
- コード (.rb)
というファイルで構成されるコンポーネントを組み合わせて作成します。
これらのファイルで記述されたエレメント (インスタンス変数やメソッドを HTML として表示する仕組み) をコードがバインディングし、HTML に変換して出力することで Web ページが表示されるようになっています。
Ruby 標準の cgi.rb で CGI を作成していると、コードやテンプレートの再利用が難しいのですが、CGIKit では Web ページのヘッダ部分 (サイトのタイトル等) やフッタ部分、またはどのページにも表示させたいパーツ等再利用したいものは全てコンポーネントとして分ける事で、コードの再利用を可能にし、開発効率を上げる事ができます。
また、CGIKit のコンポーネントは、デザインとロジックが分離されているので、ロジックに影響しないデザインだけであればコードを書き換える事無く変更する事ができます。
3. TapKit とは?
TapKit はオブジェクト-リレーショナルデータベース間のマッピングを行うフレームワークです。
細かい内容はるびま 4 号の記事「Ruby Library Report — [第3回] O/R マッピング」を参考にしてください。
4. Webアプリケーションを作ってみる
では実際に CGIKit と TapKit を使って Web アプリケーションを作成してみましょう。
今回は簡易 BBS (掲示板) を作成してみます。
手順としては以下のようになります。
- コンポーネントの作成
- モデルファイルの作成
- TapKit オブジェクト用クラスの作成
まず掲示板 (以下 BBS と呼ぶ) の操作の流れは今回以下のようにしてみます。
「スレッド一覧」画面ではスレッドの一覧を表示し、「スレッド新規登録」ではスレッドを新しく登録出来るようにします。「コメント一覧」ではスレッドに対してのコメントの一覧を表示し、またコメントを入力出来るようにします。
5. 準備
BBS の仕様は [4.Webアプリケーションを作ってみる] の通りですが、まずは CGIKit、TapKit のインストールから行いましょう。
今回 CGIKit は CVS から取得します。取得するものは安定版であるバージョン 1 系のものになります。
うまくインストール出来たでしょうか?
次に TapKit をインストールします。
今回 bbs のデータを扱うためにデータベースを使用しますが、データベースは RDBMS の PostgreSQL を利用します。
TapKit では PostgreSQL を利用するために RAA:ruby-dbi、RAA:postgres を使いますのでこれらを先にインストールしておきましょう。
ruby-dbi、ruby-postgres がインストール出来ましたら TapKit も CVS から取得します。
インストール方法は CGIKit と同じように、
となります。
これで準備は完了です。
6. コンポーネントの作成
CGIKit による Web アプリケーションは、[1. CGIKitとは] で説明したとおり、.html、.ckd、*.rb というファイル群で構成されます。これら三つのファイルを合わせてコンポーネントと呼び、画面毎にこのコンポーネントを作成していきます。
今回作成する BBS では、[4. Webアプリケーションを作ってみる] での操作の流れから、以下の三つのコンポーネントを作成します。
- MainPage (スレッド一覧)
- EditPage (スレッド新規登録)
- ThreadPage (コメント一覧)
まず MainPage コンポーネントのテンプレート、バインディングから作成します。
CGIKit のテンプレートはバインディングファイルと対となっています。
エレメントは、
や、</cgikit>を省略した形、
と記述します。
では MainPage のテンプレートを見てみましょう。
テンプレートファイル (MainPage/MainPage.html)
MainPage.html
“edit” というエレメントがまず出て来ます。これはご想像のとおりスレッドを追加するページへのリンクになります。以下のバインディングファイルでエレメントの内容を見てみましょう。
バインディングファイルは、
という書式で記述します。定義名はテンプレートで指定した名前が入り、種類は CGIKit で提供されているエレメントや他のコンポーネントを指定します。
{ と } の間はそのエレメントの属性を定義します。
例えば、edit にあたるバインディングは以下のようになります。
これは、EditPage というコンポーネントへのリンクを生成するエレメントになります。
次に thread_list というエレメントが登場します。これにあたるバインディングは以下のようになります。
これは、<cgikit> タグで囲んだ内容を繰り返すエレメントになります。
つまり、<cgikit name=”thread_list”> から </cgikit> までを繰り返すという意味になります。ここでは HTML での
のように表を 1 行ずつ繰り返す役割をしています。
thread_list の属性は、list、item、index が指定されてますが、
- list
- 繰り返すデータ。この配列から要素を順に取り出し、item 属性に入れる。
- item
- list 属性から取り出した要素。イテレータのブロックパラメータにあたる。
- index
- item 属性で繰り返される要素数。
となっています。
つまりコード (*.rb) で thread_list へ配列で値を渡すと item 属性の thread へ
1 要素ずつ展開されるようになります。ここでの配列は、
のようにコードで要素にはハッシュで値を渡すようにしています。
なのでバインディングでは、以下のように date や title といった値として thread[‘date’] や thread[‘title’] などのように指定します。
また、以下のバインディングファイルで、CKString というエレメントが記述されていますが、CGIKit が提供している各エレメントには escape という属性がありますのでこれを利用する事で自前でエスケープ等をしなくて良くなります (escape 属性はデフォルトで有効)。
エレメントの一覧は CGIKit のドキュメント を参考にすると良いでしょう。
バインディングファイル (MainPage/MainPage.ckd)
MainPage.ckd
コード (MainPage/MainPage.rb)
MainPage.rb
7. モデルファイルの作成
次に TapKit で利用するモデルファイルを作成しましょう。
TapKit ではマッピングの設定を記述したファイルをモデルファイルと呼び、このファイルには他にデータベースと接続するアダプタの情報も記述します。
まず今回作成する BBS のデータベースのテーブル構造は以下のようにします。
これを PostgreSQL に bbs という名前の DB として作成します。
次にデータベーススキーマからモデルファイルを自動生成します。
TapKit をインストールすると modeler というコマンドもインストールされますが、これが自動生成用のスクリプトになります。
モデルファイルの自動生成は以下のようにします。
(モデルファイルのファイル名は model.conf とします)
とすると、以下のように対話的に設定を行う事が出来ます。
これでカレントディレクトリに model.conf というファイル名のモデルファイルが作成されます。
以下のモデルファイルは自動生成されたファイルを若干修正しています。
具体的には text 型のフィールドで width が-1 と設定されているのを削除したり、primary key を class_properties に追加したりしています。
また、次の章で説明しますが、class_name を GenerciRecord から BBS::Thread や BBS::Comment に変更しています。
これで TapKit を利用する準備が整いました。
8. TapKit オブジェクト用クラス
次に TapKit を利用してデータベースにアクセスするクラスを作成しましょう。
CGIKit で利用する*.rb の実装では以下のようにクラスにアクセスする事を想定して作成します。
上記の通り、作成するクラス名は Thread という名前のクラスになります。
Thread クラスを作成する前に、TapKit::GenericRecord という Tapkit 独自のクラスを継承するクラスを作成します。
このクラス (BBSRecord) ではモデルファイルから TapKit の Application オブジェクトを作成します。
BBSRecord クラスの connect メソッドは index.cgi というこの BBS アプリケーションでアクセスする cgi ファイルから呼ばれるようにします。
これで以下の Thread クラスの list メソッドで@@tap という Application オブジェクトを利用出来るようになります。
以下の list メソッドでは、Quqlifer.format でデータを取得するための条件を記述します。list メソッドでは全てのスレッドを取り出したいので空を指定しています。
次に、SortOrdering.new では thread_no というフィールドで降順にデータを取り出すという並び変えの設定を行っています。SQL でいう ORDER BY 句にあたります。
FetchSpec.new ではこれらの条件式、並び変えの設定を指定し、fetchspec.limit でデータの取得件数を指定します。
実際にデータを取り出すのは、@@tap.create_editing_context.fetch で取得します。
obj には以下のような Hash に似た値が帰ってきます。
実装では
等で値を取り出す事が出来ます。
comments は FaultingDelayEvaluationArray と記述されていますが、これは comment テーブルは thread と 1:多でリレーションシップの関係を持っているため、thread_no でリレーションされている comment テーブルのデータも取得出来ます。
上記の comments は、
等でアクセス出来ますが、アクセスしない限り comment テーブルに対してデータベースにアクセスしません。これは TapKit のフォールティングの機能があるからです。
9. まとめ
簡単ですが CGIKit と TapKit で Web アプリケーションを作成してみました。
コンポーネントの再利用や O/R マッピングの利便性等は説明しきれませんでしたが、CGIKit、TapKit に興味を持っていただけると幸いです。
今回製作した BBS のソースは bbs.tar.gz になります。
CGIKit はバージョン 2 系の開発も進んでおり、リリースされた時はまたレビューしてみたいと思っております。
著者について
- 喜多川 豪
- 喜多川は株式会社ネットワーク応用通信研究所にて研究開発職に就いています。日々仕事で Ruby を使って Web アプリケーションを作成していたりします。
- かずひこ
- Web アプリケーションをこよなく愛するオープンソースエンジニア。