 | Уровень сложности: средний Тайлер Андерсон, независимый автор, Backstop Media
19.08.2009 Это третья часть серии из четырех статей о совместном использовании XForms, IBM® DB2® pureXML™ и Ruby для упрощения создания Web-приложений. В этой серии мы разрабатываем гипотетическое приложение для управления информацией о пациентах в кабинете врача. Вы получите представление об индивидуальных достоинствах каждой технологии, а также увидите, как объединить их друг с другом. В третьей части мы разработаем форму для медсестры, которая позволяет редактировать данные о пациентах; вы также узнаете, что нужно сделать в Ruby, чтобы она работала.
Введение
В части 1 этой серии из четырех статей вы начали проектировать Web-приложение, которое позволяет пациентам вводить информацию о себе в кабинете врача. Вы узнали, как создать такое приложение при помощи XForms, DB2 pureXML и Ruby on Rails, и поэкспериментировали с совместным применением этих технологий. В части 2 вы приступили к реализации приложения. Вы создали свою первую форму XForms и механизм обработки Ruby on Rails для передачи данных из формы в DB2. Теперь мы продолжим изучение этих трех технологий и посмотрим, как с их помощью использовать XML во всем приложении.
 | |
В этой третьей статье мы модернизируем пользовательский интерфейс, представленный в Ruby, чтобы можно было просматривать и редактировать существующие данные о пациентах при помощи двух новых форм: формы для редактирования данных из представления Kiosk и формы с новым представлением Triage для медсестры, которая позволяет просматривать, редактировать и подтверждать введенные пациентом данные. Когда медсестра утвердит информацию, пациент готов к осмотру врачом. Во время осмотра врач может просматривать данные о пациенте и дополнять их собственными замечаниями и результатами осмотра. В части 4 вы узнаете о структуре формы для врача, которая позволяет ему читать и редактировать данные о пациентах, подтвержденные медсестрой, и содержит дополнительные средства для ввода результатов осмотра.
Предварительные замечания
 |
Часто используемые сокращения
- CSS: Cascading Stylesheets – каскадные таблицы стилей
- URL: Uniform Resource Locator – унифицированный указатель [информационного] ресурса
- XML: Extensible Markup Language – расширяемый язык разметки
|
|
Эта статья предполагает знакомство с XML и Web-приложениями в целом. Конечно, будет полезно предварительное знакомство с тремя основными технологиями, XForms, DB2 pureXML и Ruby on Rails, но это не обязательно. При написании статьи использовался плагин Mozilla XForms версии 0.8.0.3. Он обеспечивает поддержку XForms в любом браузере Mozilla, в частности, в Firefox. Другой очень полезный плагин Mozilla — XForms Buddy. Это отладчик для XForms. Для этой статьи использовалась версия 0.5.6. Нам потребуется также сервер базы данных IBM DB2. Для этой статьи используется DB2 Express-C версии 9.5. Он работает на системах Windows®, Linux® и UNIX®. Наконец, нам потребуется Ruby on Rails. Для этой статьи используется Ruby 1.8.6 с Rails 1.2.5. В статье также применяется Web-сервер Mongrel в сочетании с Rails. Его можно получить через Ruby Gems (просто наберите в командной строке gem install). Ссылки для загрузки приведены в разделе Resources.
Редактирование данных о пациентах
Теперь пациенты могут вводить свои данные в систему, но как быть с пациентами, пришедшими на повторный прием, чью информацию надо отредактировать? Пока можно только создавать новые карточки пациентов и просматривать результаты. Теперь разработаем форму, которая позволяет редактировать и обновлять существующие записи.
Форма для редактирования данных
Возможность просматривать и редактировать существующие данные – неотъемлемая часть любого приложения, и для этого мы создадим новую форму. Создадим в общем каталоге новый файл XHTML editPatient.xhtml и заодно переименуем форму 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>
|
Довольно простые изменения, не правда ли? Во-первых, в элементе передачи id="submit-info" мы изменили URL, чтобы он указывал на сценарий редактирования Ruby. Еще мы добавили новый элемент действия, который запускается по событию xforms-ready, наступающему при загрузке формы. Это действие включает элемент передачи grab с id="load_data", извлекающий данные из новой формы. Мы увидим это дальше.
Представление и контроллер kiosk grab
Представление grab просто обращается к базе данных за записью пациента, указанного в переменной id соответствующего URL, форматирует XML и возвращает данные в форму XForms. Для реализации этого нового представления нам потребуется новый файл grab.rhtml в каталоге app\views\kiosk. Определим его следующим образом (одной строкой).
<% @headers["Content-Type"] = "text/xml; charset=utf-8" %><%= @patient.information %> |
Мы установили Content-Type заголовка в формат text/xml в соответствии с требованиями процессора XForms. Затем мы просто выводим переменную информации о пациенте, код XML, определенный для этой записи в базе данных DB2.
Однако чтобы это работало, нужно также отредактировать макет kiosk (app/views/layouts/kiosk.rhtml), чтобы он содержал только следующую строку: <%= yield %>.
В результате удаляются все лишние теги до и после данных XML, необходимых процессору XForms. На последнем шаге определяем grab в контроллере kiosk (app/controllers/kiosk_controller.rb), как показано в листинге 2.
Листинг 2. Определение grab в контроллере
def grab
id = @request.env["HTTP_REFERER"].split('=')[1]
@patient = Patient.find(id)
end
|
Обратите внимание, что код получает идентификатор пациента, взятый из указанного URL. Это делается, чтобы обойти ограничение: XForms не может передавать полученные переменные запроса GET в собственных запросах POST. Поэтому, если URL будет:
http://localhost:3000/editPatient.xhtml?id=60 |
то из базы данных будет выбрана запись с идентификатором id=60. Затем данные преобразуются в представление grab, определенное в листинге 1, которое передается в XForms.
Представление kiosk list
Теперь нужно отредактировать представление list (app/views/kiosk/list.rhtml), чтобы выводить карточки всех имеющихся пациентов со ссылками, позволяющими перейти к форме editPatient для просмотра и редактирования данных. Отредактируем это представление, как показано в листинге 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 со ссылкой Show/Edit, которая указывает на форму editPatient, причем к URL добавлен ID пациента (поэтому представление grab "знает", какую запись ему считывать из базы данных и возвращать в XForm). Внизу имеется ссылка для добавления нового пациента. Она открывает форму, созданную в части 2 данной серии статей.
Форма списка представлена на рисунке 1.
Рисунок 1. Список пациентов
Нажмите на одну из ссылок, и вы увидите форму editPatient с правильно отображаемыми существующими данными (рисунок 2).
Рисунок 2. Просмотр существующих данных в форме editPatient
Здесь можно редактировать данные. Заметьте, что при отправке формы происходит переход к сценарию kiosk/update, а не к сценарию kiosk/create, как в листинге 1. Обратите внимание на переменную id в URL, из которой контроллер grab
в листинге 2 "знает", какой id выбирать из базы данных.
Прежде чем нажать кнопку Submit Information (передать информацию), модифицируем метод записи в контроллере kiosk.
Контроллер kiosk update
Контроллер update нужно изменить так, чтобы он управлял передачей форм XForms и сохранял их в базе данных, заменяя существующие данные XML. Отредактируем контроллер kiosk, как показано в листинге 4.
Листинг 4. Редактирование метода update контроллера kiosk
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
|
Обратите внимание на сходство между этим контроллером и контроллером create. Разница между ними заключается в способе извлечения информации о пациентах с использованием URL. Сначала метод создает документ XML с данными XForms, затем извлекает карточку пациента из базы данных, заменяет существующие данные XML новыми и сохраняет их в базе данных.
Вот и все! Удивительно, как мало изменений нужно внести в пользовательский интерфейс, чтобы сделать инструмент для работы с пациентами еще более мощным. Теперь можно просматривать и редактировать существующие карточки пациентов.
Форма для утверждения медсестрой
Форма для утверждения медсестрой (triagePatient.xhtml) позволяет медсестре редактировать и утверждать данные, введенные пациентами, при помощи совсем другого представления (triage), которое мы создадим. Форма triagePatient позволяет медсестре редактировать сведения о пациентах, пользуясь только кнопкой Submit Information, а также редактировать и утверждать информацию при помощи кнопки Approve. Однако прежде чем начать работу над этой формой, нужно создать новое поле в таблице пациентов..
Изменение таблицы пациентов
Новое поле утверждения в схеме patient позволяет определять, какая информация проверена медсестрой, а какая – нет. Чтобы изменить схему patient, откройте DB2 Control Center и найдите таблицу Patients, как показано на рисунке 3.
Рисунок 3. Изменение схемы patient
Нажмите правой кнопкой на таблицу Patient и выберите Alter, как показано выше. На появившемся экране выберите Add и введите информацию о новом поле, как показано на рисунке 4.
Рисунок 4. Добавление поля утверждения
Обратите внимание на имя, тип данных, значение по умолчанию и флаг Nullable. Дважды нажмите OK. Затем Control Center должен выдать окончательное сообщение, что изменение прошло успешно, и вы увидите отредактированную схему таблицы, как показано на рисунке 5.
Рисунок 5. Отредактированная схема patient
Если вы пользуетесь DB2 Control Center, инструмент командной строки вам не понадобится.
Теперь можно приступать к созданию представления Triage.
Представление и контроллер triage
Представление и контроллер triage нужно связать с моделью patient формы для медсестры. Чтобы создать новое представление и контроллер, наберите код, показанный в листинге 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), определив grab и отредактировав контроллеры записи, как показано в листинге 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 идентичен контроллеру grab для контроллера kiosk (см. листинг 2). Единственное отличие заключается в использовании нового поля 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) и поместите его в каталог представления 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
Это последнее представление, которое нужно отредактировать, прежде чем переходить к форме для медсестры. Правильное представление списка позволяет вызывать запись пациента, сведения о котором нужно отредактировать, нажав на его имя. Отредактируйте представление 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 в список, отображая имя и фамилию, а также информацию о том, утвержден ли уже данный пациент. Благодаря оператору if, стоящему после цикла, в форме для медсестры отображаются только те пациенты, данные о которых еще не утверждены. Важно понять, как из XML извлекаются имя и фамилия. Сначала создается новый документ XML, в который передается информация XML, а затем извлекается элемент FirstName посредством обращения к doc.root.elements["FirstName"]. Точно так же извлекается фамилия пациента. Обратите внимание также на ссылку Edit/Approve. Нажимая на нее, вы попадаете в форму triagePatient, которую мы создадим дальше.
Прежде чем приступить к работе над формой triagePatient, взгляните на представление triage list (рисунок 6).
Рисунок 6. Представление triage list
Теперь перейдем к форме triagePatient.
Форма triage
Все сценарии Ruby готовы к приему данных XForms. Нужно только определить форму triagePatient. Присвойте ей имя triagePatient.xhtml и поместите в общий каталог. Определите ее, как в листинге 9.
Листинг 9. Форма triagePatient
...
</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); различия между двумя этими формами приведены выше. Элементы передачи load_data и submit-info в точности совпадают, за исключением того, что теперь они указывают на сценарий triage. Здесь есть также новый элемент передачи с идентификатором id="approve", который указывает на следующий URL (листинг 9):
http://localhost:3000/triage/update/1 |
Этот URL имеет id = 1, так что он устанавливает значение true в поле утверждения записи пациента, как показано в листинге 5. Этот элемент активизируется новой кнопкой передачи с надписью Approve (утвердить). Форма в действии показана на рисунке 7.
Рисунок 7. Представление данных о пациенте для утверждения в форме triagePatient
Чтобы установить для поля в базе данных значение true, нажмите кнопку Approve. При этом запись удаляется из списка, как показано на рисунке 8.
Рисунок 8. Утверждение сведений о пациенте
Вы успешно успешно решили задачу, поставленную в этой статье.
Заключение
Ваши знания в области Ruby, XForms и DB2 постепенно расширяются. Вы научились объединять Ruby с XForms, а также оценили удобство для пользователя СУБД DB2 и ее Control Center.
Теперь переходите к части 4, где мы создадим форму для врача, а также абсолютно новую форму для врача и медсестры, позволяющую искать пациентов по фамилии.
Загрузка | Описание | Имя | Размер | Метод загрузки |
|---|
| Код примеров для части 3 | part3_doctorsOffice.zip | 11KБ | HTTP |
|---|
Ресурсы Научиться
- Оригинал статьи (EN)
-
XForms и Ruby on Rails в кабинете врача, часть 1: Настройка IBM DB2 9 pureXML (Майкл Гальпин, developerWorks, декабрь 2007 г.): о том, как XForms, DB2 pureXML и Ruby on Rails помогают ускорить создание Web-приложений на основе XML.
-
XForms и Ruby on Rails в кабинете врача, часть 2: Создание формы ввода данных для пациентов (Майкл Гальпин, developerWorks, декабрь 2007 г.): Комбинирование XForms, DB2 pureXML и Ruby для упрощения процесса создания Web-приложения. Во второй части этой серии мы приступаем к созданию гипотетического приложения, предназначенного для работы с информацией о пациентах в кабинете врача.
-
XForms и Ruby on Rails в кабинете врача, часть 4: Создание форм для врача и для поиска карточек пациентов (Тайлер Андерсон, developerWorks, июнь 2008 г.): Интеграция XForms, IBM DB2 pureXML и Ruby для быстрого создания Web-приложений на базе XML. Полный пример приложения с новой формой XForms для поиска пациентов по фамилии.
- Чтобы как следует познакомиться с XForms, прочтите серию статей из трех частей Introduction to XForms [Введение в XForms](Chris Herbroth, developerWorks, сентябрь 2006 г.) (EN).
- Знаете ли вы, что XForms и Ajax можно использовать вместе? Вот как это делается в XForms: Combining Ajax and XForms [Комбинирование Ajax и XForms](Nicholas Chase, developerWorks, октябрь 2006 г.) .
- Углубитесь в XForms и Ajax, изучив их использование с Google Web Toolkit: Integrate XForms with the Google Web Toolkit, Part 1: Introducing GWT's JavaScript Native Interface (Michael Galpin, developerWorks, сентябрь 2007 г.) .
- Одно из первых углубленных руководств по GWT: Ajax for Java developers: Exploring the Google Web Toolkit (Philip McCarthy, developerWorks, июнь 2006 г.) .
- Начните знакомство с Ruby on Rails и DB2 с An introduction to Ruby on Rails for DB2 developers [Введение в Ruby on Rails для разработчиков DB2](Edd Dumbill, developerWorks, июнь 2006 г.) (EN).
- Все о совместном использовании DB2 и Ruby on Rails: DB2 and Ruby on Rails, Part 1: Getting started with DB2 and Ruby on Rails (John Chun, et al., developerWorks, май 2007 г.) (EN).
- Как применять pureXML из DB2 вместе с Ruby on Rails: DB2 and Ruby on Rails, Part2: DB2 and pureXML with Ruby on Rails (John Chun, et al., developerWorks, июнь 2007 г.) (EN).
- Как использовать DB2 для усиления встроенных средств тестирования в Rails: DB2 and Ruby on Rails, Part 3: Testing with DB2 and Ruby on Rails (John Chun, et al., developerWorks, июнь 2007 г.) (EN).
- Обзор последних усовершенствований DB2: Overview of new DB2 Version 9.5 pureXML enhancements (Manaj Sardana, developerWorks, ноябрь 2007 г.) (EN).
- Использование XQuery с DB2: Query DB2 XML data with XQuery (Don Chamberlin and Cynthia Saracco, developerWorks, апрель 2006 г.) .
- О библиотеке REXML для работы с XML в Ruby: XML Matters: The REXML library (David Mertz, developerWorks, март 2002 г.) (EN).
- Центр ресурсов Ajax на IBM developerWorks
- Домашняя страница XForms на сайте W3C (EN).
-
IBM XML certification: как стать сертифицированным IBM разработчиком XML и сопутствующих технологий.(EN)
-
Техническая библиотека по XML: широкий спектр технических статей, руководств, стандартов и документации IBM. (EN)
-
Технические мероприятия и Web-трансляции developerWorks.(EN)
- Книжный магазин: книги на эти и другие технические темы.(EN)
Получить продукты и технологии
Обсудить
Об авторе  | |  | Тайлер Андерсон (Tyler Anderson) получил степень бакалавра по компьютерным наукам в Brigham Young University в 2004 и степень магистра по компьютерной технике в декабре 2005 тоже в Brigham Young University. Сейчас он работает инженером в фирме Stexar Corp., расположенной в Beaverton, Ore. |
Выскажите мнение об этой странице
|  |