IBM®
Перейти к тексту
    в России и странах СНГ [изменить]    Условия использования
 
 
   
    Главная страница    Продукты    Услуги и решения    Поддержка и загрузка    Мой профиль    
Перейти к тексту

developerWorks Россия  >  XML | Information Management  >

XForms и Ruby on Rails в кабинете врача: Часть 2. Создание формы ввода данных для пациентов

developerWorks
Опции документа

Опции документа, требующие включения JavaScript, не отображаются

Обсудить

Исходные тексты примера


Выскажите мнение об этой странице

Помогите нам улучшить содержание


Уровень сложности: средний

Майкл Галпин, инженер по программному обеспечению, Vitria Technology

17.08.2009

Это вторая часть серии из четырех статей, посвященных совместному использованию XForms, IBM® DB2® pureXML™ и Ruby для упрощенного создания Web-приложений. Мы разработаем гипотетическое приложение для управления историями болезни в кабинете врача. Вы почувствуете преимущества каждой из технологий и увидите, как объединить их друг с другом. Во второй части мы приступим к реализации приложения.

Введение

В первой части этой серии из четырех статей мы начали проектировать Web-приложение, которое позволяет пациентам вводить информацию о себе в кабинете врача. Было показано, как применять XForms, DB2 pureXML и Ruby on Rails для создания такого приложения, и мы поэкспериментировали с совместным использованием этих технологий. Во второй части мы приступим к реализации приложения. Вы спроектируете свою первую форму XForms и создадите механизм Ruby on Rails для ввода данных из формы в DB2. Вы увидите, как эти три технологии можно использовать для создания приложения, всецело опирающегося на XML.



В начало


Предварительные замечания

Часто используемые сокращения
  • API: application programming interface – интерфейс прикладных программ
  • CSS: Cascading Stylesheets - каскадные таблицы стилей
  • UI: User Interface – интерфейс пользователя
  • URL: Uniform Resource Locator - унифицированный указатель [информационного] ресурса
  • XML: Extensible Markup Language - расширяемый язык разметки
  • XSD: XML Schema Definition – определение схемы XML

Эта статья предполагает знакомство с 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.



В начало


Сведения о пациенте

Другие статьи этой серии

В первой части рассказывалось, как при помощи технологий XForms, DB2 pureXML и Ruby on Rails создать интерфейс пользователя и обрабатывающую часть приложения на базе XML. Преимущество этой конструкции заключается в том, что она целиком основана на XML. Конструкция модели данных XML определяет, как реализован интерфейс пользователя на основе XForms и как извлекаются данных из DB2 с использованием Ruby on Rails в обрабатывающей части. Поэтому логично начать разработку этого приложения с конструирования модели данных XML.

Модель данных XML

Приложение позволит пациентам вводить информацию, необходимую врачу и персоналу его кабинета. Нам понадобятся такие данные, как имя пациента, его страховая компания, возраст, размер совместного платежа и, конечно, симптомы болезни. В листинге 1 приведен типичный пример такой модели.


Листинг 1. Типичный пример XML-кода сведений о пациенте
                
<?xml version="1.0" encoding="UTF-8"?>
<Info>
     <FirstName>John</FirstName>
     <MiddleName>David</MiddleName>
     <LastName>Smith</LastName>
     <Age>33</Age>
     <Insurer>HealthCo</Insurer>
     <Id>555-69-1212</Id>
     <PolicyHolder>true</PolicyHolder>
     <Copay>10</Copay>
     <Symptoms>Cough, Fever</Symptoms>
</Info>

В основном это простые строки, за несколькими исключениями. Среднее имя должно быть необязательным полем. Возраст должен быть неотрицательным целым числом. То же справедливо для суммы совместного платежа. Policy holder (наличие страховки) – это логический флаг. Идентификатор может быть трехзначным, двухзначным и четырехзначным числом. С учетом всего этого в листинге 2 приведена XML-схема для описания модели сведений о пациенте.


Листинг 2. Схема Patient
                
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://developerworks.ibm.com/patient"
           xmlns="http://developerworks.ibm.com/patient"
           elementFormDefault="qualified"
           xmlns:this="http://developerworks.ibm.com/patient">

  <xs:simpleType name="policyId">
    <xs:restriction base="xs:string">
      <xs:pattern value="[0-9]{3}-[0-9]{2}-[0-9]{4}"/>
    </xs:restriction>
  </xs:simpleType>
  
  <xs:element name="Info">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="FirstName" type="xs:NMTOKENS"/>
        <xs:element name="MiddleName" type="xs:NMTOKEN" minOccurs="0"/>
        <xs:element name="LastName" type="xs:NMTOKENS"/>
        <xs:element name="Age" type="xs:nonNegativeInteger"/>
        <xs:element name="Insurer" type="xs:NMTOKENS"/>
        <xs:element name="Id" type="this:policyId" />
        <xs:element name="PolicyHolder" type="xs:boolean"/>
        <xs:element name="Copay" type="xs:nonNegativeInteger"/>
        <xs:element name="Symptoms" type="xs:string"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Определив модель данных XML, можно создать форму XForms, которая позволяет реализовать эту модель данных.

Форма XForms для пациента

Когда известно, какие данные пациент должен вводить в приложение, XForms реализовать довольно просто. Достаточно создать элементы формы, соответствующие элементам модели данных. Тип элемента формы основан на типе данных элемента данных. С учетом этого в листинге 3 показана реализация XForms для ввода информации о пациенте.


Листинг 3. Форма для ввода сведений о пациенте
                
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:xf="http://www.w3.org/2002/xforms">
     <head>
          <meta http-equiv="Content-Type" 
		      content="text/html; charset=ISO-8859-1" />
          <title>Patient Information</title>
          <xf:model>
                  <xf:instance>
                  <Info xmlns="">
                      <FirstName/>
                      <MiddleName/>
                      <LastName/>
                    <Age/>
                    <Insurer/>
                    <Id/>
                    <PolicyHolder/>
                    <Copay/>
                    <Symptoms/>                      
                  </Info>
              </xf:instance>
              <xf:submission action="http://localhost:3000/kiosk/create" 
                                 method="post" id="submit-info"/>              
          </xf:model>
     </head>
     <body>
          <p>
               <div id="firstName">
                    <xf:input ref="FirstName">
                         <xf:label>First Name:</xf:label>
                    </xf:input>
               </div>
               <div id="middleName">
                    <xf:input ref="MiddleName">
                         <xf:label>Middle Name:</xf:label>
                    </xf:input>
               </div>
               <div id="lastName">
                    <xf:input ref="LastName">
                         <xf:label>Last Name:</xf:label>
                    </xf:input>
               </div>
               <div id="age">
                    <xf:input ref="Age">
                         <xf:label>Age:</xf:label>
                    </xf:input>          
               </div>
               <div id="insurer">
                    <xf:input ref="Insurer">
                         <xf:label>Name of Insurance Provider:</xf:label>
                    </xf:input>               
               </div>
               <div id="idNumber">
                    <xf:input ref="Id">
                      <xf:label>Insurance ID Number(###-##-####):</xf:label>
                    </xf:input>
               </div>
               <div id="holder">
                    <xf:select1 ref="PolicyHolder">
                         <xf:label>Are you the policy holder?</xf:label>
                         <xf:item>
                              <xf:label>Yes</xf:label>
                              <xf:value>true</xf:value>
                         </xf:item>
                         <xf:item>
                              <xf:label>No</xf:label>
                              <xf:value>false</xf:value>
                         </xf:item>
                    </xf:select1>     
               </div>          
               <div id="copay">
                    <xf:input ref="Copay">
                         <xf:label>Co-pay :$</xf:label>
                    </xf:input>
               </div>
               <div id="symptoms">
                    <xf:textarea ref="Symptoms">
                         <xf:label>Please describe your symptoms:</xf:label>
                    </xf:textarea>          
               </div>     
               <div id="submit">
                    <xf:submit submission="submit-info">
                         <xf:label>Submit Information</xf:label>
                    </xf:submit>
               </div>
          </p>

          <a href="kiosk/list">Back to List</a>
     </body>
</html>

Дадим краткие пояснения к листингу 3. У нас есть одна модель и одна реализация. Это пустая версия определенной выше модели сведений о пациенте. Есть также процесс передачи, входящий в состав модели. Он переносит модель по указанному в атрибуте action адресу URL. В теле формы имеется ряд элементов XForms. Каждый элемент связан с реализацией модели посредством XPath. Какие бы значения ни вводил пользователь, данные формы будут связаны с реализацией модели. Загрузив XForms в браузер, вы увидите что-то вроде того, что изображено на рисунке 1.


Рисунок 1. Форма для пациента
The patient XForms

Пусть это не самая красивая Web-страница, но это работающая форма XForms. Стоит обратить внимание на несколько интересных вещей:

  • Во-первых, это XHTML, а не обычная страница HTML. Если заменить расширение на .html или .htm, она будет обрабатываться неправильно. Дело в том, что для XForms требуется XHTML, а на странице HTML плагин Mozilla запускаться не будет.
  • Далее, так как это XHTML, CSS все же поддерживается. Это простейший способ изменить облик страницы. CSS удобно использовать для проверки данных.
  • Наконец, заметим, что в качестве адреса URL выбран http://localhost:3000/patient.xhtml. В приведенном выше примере страница обслуживается из приложения Ruby on Rails с применением Web-сервера Mongrel. Это статическая страница, поэтому можно просто скопировать ее в общий каталог своего приложения Rails. Можно использовать Web-сервер по умолчанию WEBrick, но он требует дополнительного конфигурирования для обслуживания страниц XHTML. Для Mongrel никакого такого конфигурирования не нужно.

Как уже упоминалось, передача формы вызывает действие POST экземпляра модели. Однако, прежде чем начать этот процесс, нужно выполнить некоторую проверку.

Проверка

Одна из самых типичных задач ввода данных – это проверка вводимой информации. Ее часто бывает предпочтительно выполнять со стороны клиента, чтобы предотвратить передачу в центральную систему ошибочных данных. Обычно это предусматривает написание сценария JavaScript для извлечения данных с последующим применением к ним некоторого правила (возможно, регулярного выражения). К счастью, XForms несколько упрощает эту задачу. Так как в основе XForms лежит XML, проверка имеет хорошо определенный синтаксис в XML: XML-схему. Добавим проверку XForms с помощью предварительно определенной схемы (листинг 2), как показано в листинге 4.


Листинг 4. Модель XForms со схемой проверки
                
    <title>Patient Information</title>
    <style type="text/css">
    @namespace xf url("http://www.w3.org/2002/xforms");
       xf|input {
          display: table-row;
          line-height: 2em;
       }
       
       xf|label {
          display: table-cell;
          text-align: right;
          font-family: Ariel, Helvetica, sans-serif;
          font-weight: bold;
          font-size: small;
          padding-right: 5px;
          width: 250px;
       }
	   xf|*{
		  display: table-row;
	      line-height: 2em;
	   }
       #submitLabel{
		  display: table-row;
	   }
       *:required {
           background-color: yellow;
       }
       
       *:invalid  {
          background-color: yellow;
       }
    </style>
    <xf:model id="patientModel" schema="patient.xsd">

      <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/create"
                     method="post"
                     id="submit-info"/>
    </xf:model>

Заметьте, что теперь модель ссылается на схему (patient.xsd). XForms будет загружаться и проверять эту схему автоматически. Заметьте также, что добавлены некоторые элементы CSS для отображения ошибочных данных. В браузере это должно выглядеть примерно так, как на рисунке 2.


Рисунок 2. XForms с проверкой и CSS.
XForms с проверкой и CSS

Чтобы отправить форму, пользователь должен заполнить нужные поля. Когда значение введено, цвет поля автоматически изменяется, а фокус перемещается в следующее поле формы. Подумайте, как все это пришлось бы писать на JavaScript. Вместо этого мы создали приложение при помощи XSD и некоторых элементов CSS.

XForms предоставляет много возможностей для проверки. XML-схему использовать не обязательно, но это самый простой способ, особенно если данные легко описать при помощи схемы. Если проверка выполняется на стороне клиента, на стороне сервера можно сосредоточиться на обработке переданных данных.



В начало


Передача формы

Вы, должно быть, заметили, что URL для передачи формы уже определен. Тем, кто знаком с Ruby on Rails, этот URL должен что-то напомнить. В соответствии с соглашением о конфигурации и с соглашением Rails URL /patient/create соответствует действию по созданию контроллера пациента. Это можно легко настроить с применением сценария генерации Ruby, как в листинге 5.


Листинг 5. Создание скаффолдинга для пациента
                
>ruby script/generate scaffold patient kiosk
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/kiosk
      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/kiosk/_form.rhtml
      create  app/views/kiosk/list.rhtml
      create  app/views/kiosk/show.rhtml
      create  app/views/kiosk/new.rhtml
      create  app/views/kiosk/edit.rhtml
      create  app/controllers/kiosk_controller.rb
      create  test/functional/kiosk_controller_test.rb
      create  app/helpers/kiosk_helper.rb
      create  app/views/layouts/kiosk.rhtml
   identical  public/stylesheets/scaffold.css

Это много больше, чем нам нужно. Неиспользуемые файлы можно удалить. Две важные вещи, которые здесь созданы, это класс patient и класс kiosk_controller. Класс kiosk_controller, как можно догадаться, - это контроллер, который управляет запросом из формы XForms. Теперь обратите внимание на модель и контроллер и посмотрите, как модифицировать их, чтобы сохранить XML из XForms.

Модель и контроллер Rails

Скаффолдинг Rails используется для ускорения разработки приложения. Во многих приложениях Rails скаффолдинг можно использовать для управления взаимодействием с базой данных без внесения каких-либо изменений в контроллер. Это возможно благодаря использованию кода объектно-реляционного отображения в классе ActiveRecord Rails, который является базовым классом для всех моделей (включая класс patient). ActiveRecord не предназначен для управления XML, поэтому сгенерированные классы нужно модифицировать. Начнем с класса patient (листинг 6).


Листинг 6. Класс patient по умолчанию
                
class Patient < ActiveRecord::Base
end

Как видите, по умолчанию класс Patient просто расширяет ActiveRecord. ActiveRecord динамически создает аксессоры на базе имен столбцов таблицы базы данных, которую он отображает. В нем есть конструктор, который обрамляет пары «имя/значения» знаками #. Контроллер приложения использует это, чтобы легко передать их прямо в форму данных. Этим можно воспользоваться для модификации класса patient (листинг 7).


Листинг 7. Модифицированный класс patient
                
require 'rexml/document'

class Patient < ActiveRecord::Base
  def information=(value)
    self[:information] = value.to_s
  end    
end

Это мелкое, но важное изменение. Мы хотим хранить информацию в виде строки, и ActiveRecord вставит ее в базу данных как строку. Но что будет передано в нашу модель? Этим управляет контроллер. В листинге 8 показан контроллер по умолчанию.


Листинг 8. Контроллер Kiosk по умолчанию
                
class KioskController < ApplicationController
  def index
    list
    render :action => 'list'
  end

  # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
  verify :method => :post, :only => [ :destroy, :create, :update ],
         :redirect_to => { :action => :list }

  def list
    @patient_pages, @patients = paginate :patients, :per_page => 10
  end

  def show
    @patient = Patient.find(params[:id])
  end

  def new
    @patient = Patient.new
  end

  def create
    @patient = Patient.new(params[:patient])
    if @patient.save
      flash[:notice] = 'Patient was successfully created.'
      redirect_to :action => 'list'
    else
      render :action => 'new'
    end
  end

  def edit
    @patient = Patient.find(params[:id])
  end

  def update
    @patient = Patient.find(params[:id])
    if @patient.update_attributes(params[:patient])
      flash[:notice] = 'Patient was successfully updated.'
      redirect_to :action => 'show', :id => @patient
    else
      render :action => 'edit'
    end
  end

  def destroy
    Patient.find(params[:id]).destroy
    redirect_to :action => 'list'
  end
end

Ранее мы определили действительный URL для XForms как /kiosk/create, поэтому будет вызван приведенный выше метод create. Rails «думает», что это последовательность элементов формы HTML, а не документ XML. Поэтому мы слегка модифицируем этот метод, чтобы обрабатывать XML-документ, который передается написанной нами формой XForms. В листинге 9 показан модифицированный метод create.


Листинг 9. Модифицированный метод create
                
  def create
    doc = REXML::Document.new("<Info></Info>")
    params[:Info].each_pair do |key,value|
      if (key.index(':') == nil) #namespace attributes 
        el = REXML::Element.new key
        el.add_text value
        doc.root.add el
      else
        doc.root.add_attribute key,value
      end
    end
    @patient = Patient.new
    @patient.information = doc
    if @patient.save
      flash[:notice] = 'Patient was successfully created.'
      redirect_to :action => 'list'
    else
      render :action => 'new'
    end
  end

Первое, что бросается в глаза, - это то, что для создания XML-документа используется REXML. Это стандартная библиотека в составе Ruby. XML-документ из XForms поступает в параметр Info и обрабатывается как объект. Достаточно повторить его и вернуть в XML, и Rails введет документ в базу данных. Теперь его можно испытать.



В начало


Тестирование приложения

Чтобы испытать приложение, запустите сервер обычной командой ruby script/server start. Затем наведите браузер на XForms, как на рисунке 2. Заполните форму и нажмите на кнопку Submit Information (передать информацию). Вы увидите экран, изображенный на рисунке 3.


Рисунок 3. Список пациентов
Список пациентов

Откуда взялся пользовательский интерфейс? Это стандартный UI списка, предоставляемый скаффолдингом Rails. Заметьте, что в поле Info он отображает неформатированный текст XML. Если прокрутить экран вправо, вы увидите элементы управления для просмотра, редактирования и удаления пациентов. Просмотр и удаление работают как надо. Но не работает редактирование, и ссылка New Patient (новый пациент) внизу экрана тоже не работает. Нужно модифицировать ссылки для XForms, так как именно он используется для ввода данных. В этом вам поможет часть 3 настоящей серии статей.



В начало


Заключение

Мы рассмотрели применение XForms для создания формы ввода данных о пациентах. XForms обеспечивает включение этих данных в XML-документ и даже может выполнить проверку по схеме XML. Приложение передает этот XML-документ в контроллер Ruby on Rails. Ruby облегчает обработку этих данных как XML и преобразует XML в строку. DB2 распознает XML, преобразованный в последовательную строку, и может сохранять его в естественном виде с использованием технологии pureXML. Rails может даже отобразить эти данные без какой-то специальной работы с вашей стороны. Теперь можно использовать синтаксис DB2 XML/SQL для запроса XML-данных или для их извлечения, а Ruby – для навигации и выборки данных.




В начало


Загрузка

ОписаниеИмяРазмерМетод загрузки
Код примеров для Части 2part2_doctorsOffice.zip7KBHTTP
Информация о методах загрузки


Ресурсы

Научиться

Получить продукты и технологии

Обсудить


Об авторе

Майкл Галпин (Michael Galpin) имеет учёную степень по математике в Калифорнийском Технологическом институте. Он является Java-разработчиком с конца 90-х гг. и работает инженером по программному обеспечению в Vitria Technology, в Саннивейл, Калифорния.




Выскажите мнение об этой странице


Пожалуйста, найдите минутку и заполните форму, чтобы повысить уровень сервиса.



 


 


 


Поделиться этой статьей:

забобрить забобрить memori сохранить в memori




В начало


IBM обладает всеми авторскими правами касательно информации, расположенной на developerWorks. Использование информации приведенной на этом ресурсе без явного письменного разрешения от IBM или первоначального автора запрещены. Если Вы желаете использовать информацию с developerWorks, пожалуйста воспользуйтесь регистрационной формой для того, чтобы связаться с нами запрос на использование материалов developerWorks Россия.
    IBM в России Конфиденциальность Контакты