レベル: 中級 Tyler Anderson (tyleranderson5@yahoo.com), Freelance writer
2008年 06月 03日 更新 2008年 12月 04日 この記事は、XForms と IBM® DB2® pureXML™、そして Ruby を一緒に使うことで容易に Web アプリケーションを作成する 4 回シリーズの第 3 回です。このシリーズでは、病院で患者の情報を管理するための仮定のアプリケーションを作成し、XForms、DB2 pureXML、そして Ruby on Rails それぞれの技術が個々に持つ強みの一端を知ると共に、これらの技術を併せて使用する方法も学びます。シリーズ第 3 回目の今回は、看護師が患者のデータに戻って編集するためのフォームを作成し、またこれを Ruby で実現するには何をすればよいかを学びます。
2008年 12月 04日 - 読者からのコメントに対応し、3 つのディレクトリー名の例 (app/view/...、app/model/...、app/controller/...) をそれぞれ次のディレクトリー名に変更しました。リスト 6 の後の 2 段落目と「triage の list ビュー」セクションの 1 段落目の app/view/... を app/views/... に、「patient クラス」セクションの 1 段落目の app/model/... を app/models/... に、そして「Kiosk の grab ビューとコントローラー」セクションの 4 段落目の app/controller/... を app/controllers/... に変更しました。
はじめに
この 4 回シリーズの第 1 回では、病院で患者が情報を入力するための Web アプリケーションの設計を開始しました。そこでは、そうしたアプリケーションを作成するために XForms と DB2 pureXML、そして Ruby on Rails をどのように使えばよいかを説明し、これらの技術を一緒に使っていくつかの実験を行いました。第 2 回ではアプリケーションの実装を開始しました。最初の XForms を設計し、そのフォームから DB2 にデータを挿入するための Ruby on Rails のバックエンドを作成しました。今回もその続きとして、これらの 3 つの技術をどのように使用すればアプリケーション全体にわたって XML を活用できるのかを学びます。
この第 3 回では、Ruby で表現されたユーザー・インターフェースを改善し、2 つの新しいフォームを使って既存の患者のデータの表示と編集ができるようにします。フォームの 1 つは Kiosk のビューから患者データを編集するためのフォーム、もう 1 つは入力された患者データを看護師が新しい Triage ビューで表示、編集、承認するための新しいフォームです。入力された情報を看護師が承認すると、その患者は医師の診断を受けることができます。患者が医師の診察を受ける際には、医師はその患者のデータを表示することができ、その医師自身が気付いた事項や注記を補足することができます。第 4 回では医師用のフォームの構造について学びます。このフォームでは、看護師が承認した患者データを医師が見たり編集したりすることができ、またその医師による診察の結果を追加して入力することができます。
前提条件
 |
頻繁に使用する頭字語
- CSS: Cascading Stylesheets
- URL: Uniform Resource Locator
- XML: Extensible Markup Language
|
|
この記事では XML と Web アプリケーションに関して全般的に慣れていることを前提としています。これまでに 3 つのコア技術 (XForms とDB2 pureXML、そして Ruby on Rails) を経験したことがあれば役立ちますが、決してそれが必須なわけではありません。この記事を執筆するにあたり、Mozilla XForms プラグインのバージョン 0.8.0.3 を使用しました。このプラグインによって、Firefox を始めとするすべての Mozilla ブラウザーで XForms ランタイムをサポートすることができます。もう 1 つ、Mozilla 用の非常に便利なプラグインが XForms 用のデバッガーである XForms Buddy です。この記事では XForms Buddy のバージョン 0.5.6 を使用しました。また IBM の DB2 データベース・サーバーも必要です。この記事では Windows® システムと Linux® システム、そして UNIX® システムで使用できる DB2 Express-C バージョン 9.5 を使用しています。最後に、Ruby on Rails が必要です。この記事では Ruby 1.8.6 と Rails 1.2.5 を使用しています。また Rails と合わせて Mongrel Web サーバーも使っています。Mongrel は Ruby Gems から入手することができます (コマンドラインから gem gem install mongrel と入力すればよいだけです)。ダウンロード用のリンクは「参考文献」を参照してください。
既存の患者データを編集する
患者が自分のデータをシステムに入力できるようになったら、情報の更新が必要な患者が再度自分の情報を操作できるためにはどうすればよいのでしょう。現状では、新しい患者を作成することと、結果を表示することしかできません。そこで今度は、既存の患者情報の編集と更新を行えるフォームを作成します。
患者用の編集フォーム
どのようなアプリケーションでも、既存データの表示と編集の機能は必須の機能です。ここではそれを、新しいフォームによって実現します。そこで公開ディレクトリーに新しい XHTML ファイル editPatient.xhtml を作成し、第 2 回の patient.xhtml フォームは newPatient.xhtml とリネームしておきます。新しく作成された editPatient フォームは newPatient フォームと非常によく似ています。どこが変更されているのかを見てください (リスト 1)。
リスト 1. editPatient フォームを作成する
...
<xf:model id="patientModel">
<xf:instance xmlns="" id="patient">
<p:Info>
<FirstName></FirstName>
<MiddleName></MiddleName>
<LastName></LastName>
<Age></Age>
<Insurer></Insurer>
<Id></Id>
<PolicyHolder></PolicyHolder>
<Copay></Copay>
<Symptoms></Symptoms>
</p:Info>
</xf:instance>
<xf:submission action="http://localhost:3000/kiosk/update/0"
method="post"
id="submit-info"/>
<xf:submission id="load_data"
action="http://localhost:3000/kiosk/grab/0"
method="post"
replace="instance"
/>
<xf:action ev:event="xforms-ready">
<xf:dispatch name="xforms-submit" target="load_data"/>
</xf:action>
</xf:model>
...
<a href="kiosk/list">Back to List</a>
</body>
</html>
|
ご覧のとおり非常に単純な変更です。第 1 に、id="submit-info" を持つ submission 要素の中で、Ruby の更新スクリプトを指すように action 属性の値に指定されている URL を変更しています。また、xforms-ready イベント発生時に呼び出される新しい action 要素を追加しています (xforms-ready イベントはフォームがロードされるとトリガーされます)。この呼び出されたアクションによって、id="load_data" を持つ submission 要素がディスパッチされ、新しいビューである grab からデータが取得されます。では、この新しいビューを見てみましょう。
Kiosk の grab ビューとコントローラー
grab ビューは単純に、このビューへの遷移元の URL に含まれる id 変数で示される患者レコードを検索するためにデータベースに問い合わせを行い、その結果得られた XML を適切なフォーマットにして XForms に返送します。この新しいビューを実装するためには、app\views\kiosk ディレクトリーの中に新しいファイル grab.rhtml が必要です。このファイルを次のように (1 行で) 定義します。
<% @headers["Content-Type"] = "text/xml; charset=utf-8" %><%= @patient.information %> |
これだけです。これによって、ヘッダーの Content-Type を、XForms プロセッサーに必要なフォーマットである text/xml に設定することができました。そして、patient.information 変数、つまりDB2 データベースのその患者レコードに対して定義された XML を出力します。
しかしこれを動作させるためには、Kiosk のレイアウト (app/views/layouts/kiosk.rhtml) を編集し、<%= yield %> という行のみを含むようにする必要もあります。
これによって、XForms プロセッサーに必要な XML データの前後にある余分なタグがすべて削除されます。このフローの最後のステップは、Kiosk コントローラー (app/controllers/kiosk_controller.rb) の中で grab を定義することです (リスト 2)。
リスト 2. Kiosk コントローラーの中で grab を定義する
def grab
id = @request.env["HTTP_REFERER"].split('=')[1]
@patient = Patient.find(id)
end
|
このコードが、遷移元の URL から得られる患者の id を取得することに注意してください。これによって、XForms は受信した GET リクエスト変数をその XForms による POST リクエストの中で送信することはできない、という制約を克服することができます。従って、URL が下記のような場合、
http://localhost:3000/editPatient.xhtml?id=60 |
データベースから抽出されるレコードは、id が60 であるレコードです。このデータは、リスト 1 で定義した grab ビューに渡され、そして XForms に渡されます。
Kiosk の list ビュー
次に、現在のすべての患者をリンク付きで一覧表示するように list ビュー (app/views/kiosk/list.rhtml) を変更する必要があります。この変更を行うと、editPatient フォームから患者の表示と編集を適切に行えるようになります。list ビューはリスト 3 のように変更します。
リスト 3. list ビューを変更する
<h1>Listing patients</h1>
<table>
<tr>
<th><%= "ID" %></th>
</tr>
<% for patient in @patients %>
<tr>
<td><%=h patient.id %></td>
<td><%= "<a href=\"../editPatient.xhtml?id=" +
patient[:id].to_s + "\">Show/Edit</a>" %></td>
<td><%= link_to 'Delete', { :action => 'destroy',
:id => patient },
:confirm => 'Are you sure?',
:method => :post %></td>
</tr>
<% end %>
</table>
...
<br />
<a href="/newPatient.xhtml">New patient</a>
|
表示される列が変更されていることに注意してください。ここでは ID 列を表示し、その隣に editPatient フォームを指す Show/Edit リンクを表示しています。この Show/Edit リンクのリンク先の URL の末尾には ID が付けられています (このように URL の末尾に ID を付けておくことで、grab ビューは、どのレコードをデータベースから読み取って XForms に返せばよいのかを知ることができます)。
一番下にある、新しい患者を追加するためのリンクに注意してください。このリンクをクリックすると、このシリーズの第 2 回で作成したフォームが開きます。
このフォームを見てみましょう (図 1)。
図 1. 患者を一覧表示する
リンクの 1 つをクリックすると、editPatient フォームが表示され、既存のデータが適切に表示されます (図 2)。
図 2. editPatient フォームの中に既存のデータを表示する
ここでは必要に応じてデータを編集することができます。このフォームを送信すると、(リスト 1 に定義されているように) kiosk/create スクリプトに行かずに kiosk/update スクリプトに行くことに注意してください。また、URL に含まれる id 変数に注意してください。この変数によって、リスト 2 の grab コントローラーはどの id をデータベースから取得すればよいかを知ることができます。
Submit Information ボタンを選択する前に、Kiosk コントローラーの update メソッドを変更する必要があります。
Kiosk の update コントローラー
XForms の送信データを処理し、そのデータをデータベースに保管して既存の XML データと置き換えられるように、update コントローラーを変更します。そのために Kiosk コントローラーをリスト 4 の定義のように変更します。
リスト 4. Kiosk コントローラーの update メソッドを変更する
def update
doc = REXML::Document.new("<Info></Info>")
params[:Info].each_pair do |key,value|
if (key.index(':') == nil) #removes
el = REXML::Element.new key
el.add_text value
doc.root.add el
else
doc.root.add_attribute key,value
end
end
id = @request.env["HTTP_REFERER"].split('=')[1]
@patient = Patient.find(id)
@patient.information = doc
@patient.update_attributes(params[:patient])
redirect_to :action => 'list'
end
|
この update コントローラーと create コントローラーとが似ていることに注意してください。両者の異なる点は、update コントローラーでは現在のビューへの遷移元の URL を使って既存の患者情報を取得するところにあります。この update メソッドは、まず XForms 送信データの XML 文書を作成し、次にデータベースから既存の患者のデータを取得し、既存の XML データを新しいデータと置き換え、そしてその新しいデータをデータベースに保管します。
それで終わりです。ユーザー・インターフェースを少し変更するだけで、患者用のツールが非常に強力なものになりました。これで、既存の患者レコードを表示して、更新できるようになったのです。
看護師用の承認フォーム
看護師用の承認フォーム (triagePatient.xhtml) では、患者が入力したデータを、これから作成するまったく別のビュー (triage) から看護師が編集し、承認することができます。triagePatient フォームでは、看護師が Submit Information ボタンのみを使って患者情報を編集することができ、また Approve ボタンを使って患者情報の編集と承認を行うことができます。しかしこのフォームのための作業を始める前に patients テーブルに新しいフィールドが必要なので、まずはこのフィールドを追加します。
patients テーブルを変更する
patient スキーマの新しい approve フィールドでは、どの情報を看護師が承認しており、どの情報を承認していないのかを判断することができます。patient スキーマを変更するためには、DB2 のコントロール・センター (Control Center) を開き、Patients テーブルを参照します (図 3)。
図 3. patient スキーマを変更する
Patient テーブルを右クリックし、変更 (Alter) をクリックします (上図)。表示される画面上で追加 (Add) をクリックし、新しいフィールドの情報を入力します (図 4)。
図 4. approved フィールドを追加する
列名 (Column name) とデータ型 (Data type)、デフォルト値 (Default value)、そして NULL 可能 (Nullable) に注目してください。OK を 2 回クリックします。すると、変更が成功したことをコントロール・センターが最終通知として知らせ、図 5 のような更新されたテーブルのスキーマが表示されるはずです。
図 5. 更新された patient スキーマ
DB2 のコントロール・センターを使用する場合には、コマンドライン・ツールを使用する必要はありません。
これで triage ビューを作成する準備が整いました。
triage のビューとコントローラー
triage のビューとコントローラーを看護師用の XForms の患者モデルと関連付けます。新しいビューとコントローラーを作成するためには、リスト 5 のコードを入力します。
リスト 5. triage のビューとコントローラーを作成する
ruby script/generate scaffold patient triage
exists app/controllers/
exists app/helpers/
create app/views/triage
exists app/views/layouts/
exists test/functional/
dependency model
exists app/models/
exists test/unit/
exists test/fixtures/
skip app/models/patient.rb
identical test/unit/patient_test.rb
identical test/fixtures/patients.yml
create app/views/triage/_form.rhtml
create app/views/triage/list.rhtml
create app/views/triage/show.rhtml
create app/views/triage/new.rhtml
create app/views/triage/edit.rhtml
create app/controllers/triage_controller.rb
create test/functional/triage_controller_test.rb
create app/helpers/triage_helper.rb
create app/views/layouts/triage.rhtml
identical public/stylesheets/scaffold.css
|
ここで triage コントローラー (app/controllers/triage_controller.rb) に変更を加えます。その内容は、triage コントローラーの中で grab を定義し、さらにこのコントローラー内にある update コントローラーを変更します (リスト 6)。
リスト 6. triage コントローラーを編集する
def grab
id = @request.env["HTTP_REFERER"].split('=')[1]
@patient = Patient.find(id)
end
def update
doc = REXML::Document.new("<Info></Info>")
params[:Info].each_pair do |key,value|
if (key.index(':') == nil) #removes
el = REXML::Element.new key
el.add_text value
doc.root.add el
else
doc.root.add_attribute key,value
end
end
id = @request.env["HTTP_REFERER"].split('=')[1]
@patient = Patient.find(id)
@patient.information = doc
approvedCode = params[:id]
if approvedCode == "1" then
@patient.approved = "true"
end
@patient.update_attributes(params[:patient])
redirect_to :action => 'list'
end
|
grab が、Kiosk コントローラーの grab コントローラー (リスト 2) と同じであることに注意してください。update コントローラーの唯一の違いは、データベースに新たに追加された approved フィールドを使っていることです。この値が ID フィールドから取得されていることに注意してください。従って、このレコードを更新するために呼び出される更新用の URL が http://localhost:3000/triage/update/1 の場合には、この患者は承認されます。
最後に、triage のレイアウト (app/views/layouts/triage.rhtml) に簡単な変更を加え、このレイアウトを Kiosk のレイアウトと同じように定義します (<%= yield %>)。grab ビューが動作するためには、このようにする必要があるのです。ところで grab ビューと言えば、Kiosk ビュー (app/views/kiosk/grab.rhtml) から grab ビューをコピーし、それを triage ビューのフォルダー (app/views/triage) にコピーする必要があります。これで grab のビューとコントローラーは準備完了です。
次に、patient クラス (patient.rb) を、データベースの新しいフィールドに対応するように変更します。
patient クラス
approved 変数をデータベースに保管するためには、patient クラス (app/models/patient.rb) を変更する必要があります (リスト 7)。
リスト 7. patient クラスを変更する
class Patient < ActiveRecord::Base
def information=(value)
self[:information] = value.to_s
end
def approved=(value)
self[:approved] = value.to_s
end
end
|
これで patient クラスの準備が整いました。今度は list ビューを変更します。
triage の list ビュー
この triage の list ビューの変更が、ビューの変更の最後になります。これが終わると、次は nurse フォームに取り組みます。この変更では、患者の名前をクリックすればその患者の情報を編集できるように list ビュー (app/views/triage/list.rhtml) を変更します (リスト 8)。
リスト 8. list ビューを変更する
<h1>Listing patients</h1>
<table>
<tr>
<th><%= "First Name" %></th>
<th><%= "Last Name" %></th>
<th><%= "Approved" %></th>
</tr>
<% for patient in @patients %>
<% if patient.approved=="false" then %>
<tr>
<td><% doc = REXML::Document.new(patient.information) %>
<%= doc.root.elements["FirstName"] %>
</td>
<td>
<%= doc.root.elements["LastName"] %>
</td>
<td><%=h patient.approved %></td>
<td><%= "<a href=\"../triagePatient.xhtml?id=" +
patient[:id].to_s + "\">Edit/Approve</a>" %></td>
<td><%= link_to 'Destroy', { :action => 'Delete', :id => patient },
:confirm => 'Are you sure?',
:method => :post %></td>
</tr>
<% end %>
<% end %>
</table>
...
|
ここでは実験として、XML から患者の苗字 (First Name) と名前 (Last Name) を患者情報のリストに追加して表示し、さらにその患者の情報が既に承認されているかどうかを表示しています。また for ループの後の if 文によって、情報がまだ承認されていない患者のみを看護師に対して表示しています。ここで注目すべき重要な点は、苗字と名前がどのようにして XML から取得されているかという点です。まず新しい XML 文書が作成されて XML 情報が渡され、次に doc.root.elements["FirstName"] への呼び出しによって FirstName 要素が取得されます。LastName 要素もこれと同じ方法で取得されます。また Edit/Approve リンクを調べてみてください。このリンクをクリックすると、これから作成する triagePatient フォームが表示されます。
triagePatient フォームに取り組む前に、triage の list ビューを見てみましょう (図 6)。
図 6. triage の list ビュー
それでは、triagePatient フォームの作成に移ります。
triage の XForms
すべての Ruby スクリプトは XForms の送信データを受け付ける準備が整っています。あとは triagePatient の XForms を定義すればよいだけです。この XForms には triagePatient.xhtml という名前を付けて、公開フォルダーに置くようにしてください。この XForms はリスト 9 のように定義します。
リスト 9. triagePatient の XForms
...
</p:Info>
</xf:instance>
<xf:submission action="http://localhost:3000/triage/update/0"
method="post"
id="submit-info"/>
<xf:submission action="http://localhost:3000/triage/update/1"
method="post"
id="approve"/>
<xf:submission id="load_data"
action="http://localhost:3000/triage/grab/0"
method="post"
replace="instance"
/>
<xf:action ev:event="xforms-ready">
<xf:dispatch name="xforms-submit" target="load_data"/>
</xf:action>
...
<xf:label>Submit Information</xf:label>
</xf:submit>
</div>
<div id="approve">
<xf:submit submission="approve">
<xf:label>Approve</xf:label>
</xf:submit>
</div>
</p>
<a href="triage/list">Back to List</a>
</body>
</html>
|
リスト 9 のフォームは editPatient フォーム (リスト 1) と似ているため、この 2 つの間で異なる部分を上に示してあります。load_data と submit-info という submission 要素はまったく同じですが、今度は triage のスクリプトを指している点が異なります。また、triagePatient には id="approve" を持つ新しい submission 要素もあります。この要素は上のリスト 9 を見るとわかるように、次の URL を指しています。
http://localhost:3000/triage/update/1 |
この URL は 1 という id を持っており、従って患者のレコードの approved フィールドは真に設定されます。これについては先ほど triage の update コントロールで示したとおりです (リスト 5)。Approve というラベルの付いた新しい送信ボタンによって、この新しい submission 要素が有効になります。この XForms の実際を図 7 で見てください。
図 7. triagePatient フォームで承認用の患者データを表示する
データベースの approved フィールドを真に設定するためには Approve をクリックします。これによって、その患者が list ビューから削除されます (図 8)。
図 8. 患者情報を承認する
これで、この記事の概要部分で説明した作業を無事に完了することができました。
まとめ
Ruby と XForms、そして DB2 に関する皆さんのスキルは確実に向上しています。ここでは Ruby と XForms を統合する方法と、DB2 と DB2 のコントロール・センターを使う楽しさと便利さを学びました。
第 4 回にもご期待ください。第 4 回では医師用のフォームを作成します。その中には医師と看護師が患者の苗字で情報を参照できる、まったく新しいフォームも含まれています。
ダウンロード | 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|
| Part 3 sample code | part3_doctorsOffice.zip | 11KB | HTTP |
|---|
参考文献 学ぶために
製品や技術を入手するために
議論するために
著者について  | |  | Tyler Anderson は、2004年に Brigham Young University でコンピューター・サイエンスの学位を取得し、2005年12月に同大学のコンピューター・エンジニアリングの理学修士を取得して、同大学を卒業しました。Tyler はフリーランス・ライターであり、Backstop Media のライターでもあります。 |
記事の評価
|