curl_scaffoldジェネレータを作る
Ruby on Railsのジェネレータは、前ページで説明したRailsのコード自身以外に、プロジェクトのlibディレクトリやホームデイレクトリ下の.rails/generatorsデイレクトリにも作れます。
今回はホームデイレクトリ下にcurl_scaffoldデイレクトリを作り、そこにジェネレータを作ることにします。Windowsの場合はC:¥Documents and Settings¥Owner¥.rails¥generators¥curl_scaffoldなどになると思います。
curl_scaffoldジェネレータのファイル構成は以下のようになります。各ファイルについてはこれから説明します。
curl_scaffold用start.html.erbテンプレート
前回作ったリッチクライアント版のCRUDアプリのメインはapp/view/player/start.html.erbです。このファイルをジェネレータ用のテンプレートに変換することがcurl_scaffold作成の中での大きな仕事です。
それでは、順番にテンプレート化していきましょう。
属性(カラム)の置き換え
start.html.erbの中には、playersテーブルのカラムに対応した記述が多数あります。下のコードではRecordFieldの部分が各カラムに対応したフィールドの定義です。
{curl 7.0 applet} {curl-file-attributes character-encoding = "utf8"} {import * from CURL.IO.JSON} {let players: RecordSet = {RecordSet {RecordFields {RecordField "id", caption = "id", domain = int} , {RecordField "name", caption = "name", domain = String} , {RecordField "team", caption = "team", domain = String} , {RecordField "no", caption = "no", domain = int} , {RecordField "goal", caption = "goal", domain = int} , {RecordField "assist", caption = "assist", domain = int} } } }
下が対応するview_start.html.erbテンプレートです。
{curl 7.0 applet} {curl-file-attributes character-encoding = "utf8"} {import * from CURL.IO.JSON} {let <%= plural_name %>: RecordSet = {RecordSet {RecordFields {RecordField "id", caption = "id", domain = int} , <% for attribute in attributes -%> {RecordField "<%= attribute.name %>", caption = "<%= attribute.name %>", domain = <%= attribute.curl_type %>} <%= attribute.last ? '' : ',' %> <% end -%> } } }
Scaffoldジェネレータではこのカラム情報はattributesという属性(GeneratedAttributeクラスのインスタンス)の配列に入っており、nameには名前、curl_typeには型の情報が入っています。さらにlastはattributes配列の最後の要素のみがtrueになります。そのため","区切りを最後以外に付けています。
また、playersテーブルに対応した複数形の名前はplural_nameに、単数形の名前はsingular_nameに入っているので、テーブル名に対応した変数名や関数名などを<%= ~ %>で置き換えていきます。
汎用化
前回のstart.html.erbではカラムの表示幅などはデータの大きさによりきめ細かく指定していましたが、
{let data_list: RecordGrid = {RecordGrid width = 16cm, height = 6cm, record-source = players, {RecordGridColumn "id", width = 0}, {RecordGridColumn "name", width = 5cm}, {RecordGridColumn "team", width = 2cm}, {RecordGridColumn "no", width = 2cm}, {RecordGridColumn "goal", width = 3cm, halign = "right"}, {RecordGridColumn "assist", width = 3cm, halign = "right"} } }
ジェネレータでは、このような細かい指定は無理なので無難な形で統一してしまいました。
{let data_list: RecordGrid = {RecordGrid width = <%= attributes.size * 3 %>cm, height = 6cm, record-source = <%= plural_name %>, {RecordGridColumn "id", width = 0}, <% for attribute in attributes -%> {RecordGridColumn "<%= attribute.name %>", width = 3cm} <%= attribute.last ? '' : ',' %> <% end -%> } }