Автор: Stuart Eccles
Перевод: Андрей Горбатов
Оригинал статьи
У вас должны быть установлены Ruby on Rails 1.1 и база данных. Если Ruby on Rails не установлен, загляните на InstantRails для Windows или Locomotive для Mac. Также вам необходим установленный Flex Builder. Вы можете, конечно, использовать компилятор Flex, но Builder IDE намного удобнее и проще. Скачать Flex2.0 beta можно на сайте Adobe Labs. Если у вас Windows, просто установите Flex Builder, который будет включать все, что нужно, включая Flash Player 9 beta. В противном случае, вам необходимо установить Flash Plyaer 9 beta и Flex SDK отдельно.
Сначала создадим Rails приложение. Из командной строки выполним:
rails flexiblerails
Вам также необходима база данных. Назовем ее flexiblerails_development.
Создадим таблицу reviews в базе данных:
DROP DATABASE IF EXISTS `flexiblerails_development`;
CREATE DATABASE `flexiblerails_development`
USE `flexiblerails_development`;
CREATE TABLE `reviews` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(255) default NULL,
`text` text,
`score` int(11) default NULL,
`author` varchar(120) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

Создадим модель и контроллер:
ruby script/generate model Review
ruby script/generate controller Reviews
Основа приложения создана.
Если вы используете Flex Builder, то это будет легко. Запустите Flex Builder и выберите в меню File > New > Flex Application. Вам не нужно использовать Flex dataservices, поэтому просто назовите приложение flexiblerails и нажмите Finish.
Перед вами будет новый MXML файл:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" layout="absolute">
</mx:Application>
Вот и все.
Сначала простой скаффолдинг. Мы хотим, чтобы Flex приложение отображало список Reviews в таблице.
Создадим Rails бэкэнд. Откройте app/controllers/reviews_controller.rb. Замените содержимое файла на следующий код:
class ReviewsController < ApplicationController
def list
@reviews = Review.find :all
render :xml => @reviews.to_xml
end
end
Rails 1.1 делает вывод модели в виде XML очень простым.
Запустите сервер:
ruby script/server
Добавим данные в базу данных:
INSERT INTO `reviews` (`id`,`title`,`text`,`score`,`author`) VALUES (1,'Agile Web Development with Rails','This is the text for Rails programming and a fine read all round',5,'David Heinemeier Hansson');
INSERT INTO `reviews` (`id`,`title`,`text`,`score`,`author`) VALUES (2,'Programming Rails','Rubby Russell\'s new Rails book for O\'Reilly. Highly anticipated.',4,'Robby Russell');
Теперь проверим Rails контроллер. Откройте http://localhost:3000/reviews/list и вы увидите результирующий XML.
<reviews>
<review>
<score type="integer">5</score>
<title>Agile Web Development with Rails</title>
<text>
This is the text for Rails programming and a fine read all round
</text>
<author>David Heinemeier Hansson</author>
<id type="integer">1</id>
</review>
<review>
<score type="integer">4</score>
<title>Programming Rails</title>
<text>
Rubby Russell's new Rails book for O'Reilly. Highly anticipated.
</text>
<author>Robby Russell</author>
<id type="integer">2</id>
</review>
</reviews>
Давайте передадим этот XML во Flex. Во Flex Builder замените содержимое файла flexiblerails.mxml на следующий код:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" layout="absolute" creationComplete="reviewRequest.send()">
<mx:HTTPService id="reviewRequest" url="http://localhost:3000/reviews/list" useProxy="false"/>
<mx:DataGrid id="dgReviews" x="40" y="85" width="800" height="134" dataProvider="{reviewRequest.lastResult.reviews.review}">
<mx:columns>
<mx:DataGridColumn headerText="Title" dataField="title" width="480"/>
<mx:DataGridColumn headerText="Author" dataField="author" width="240"/>
<mx:DataGridColumn headerText="Score" dataField="score" width="80"/>
</mx:columns>
</mx:DataGrid>
<mx:TextArea x="40" y="245" width="800" htmlText="{dgReviews.selectedItem.text}" />
</mx:Application>
Этот MXML код создает следующее:
<mx:HTTPService id="reviewRequest" url="http://localhost:3000/reviews/list" useProxy="false"/>
Создает HTTPService, который получет доступ к действию list контроллера ReviewsController.
<mx:DataGrid id="dgReviews" x="40" y="85" width="800" height="134" dataProvider="{reviewRequest.lastResult.reviews.review}">
<mx:columns>
<mx:DataGridColumn headerText="Title" dataField="title" width="480"/>
<mx:DataGridColumn headerText="Author" dataField="author" width="240"/>
<mx:DataGridColumn headerText="Score" dataField="score" width="80"/>
</mx:columns>
</mx:DataGrid>
Здесь создается DataGrid - это таблица для отображения данных.
Атрибут dataProvider указывает на результат HTTPService с помощью
reviewRequest.lastResult. reviews.review – это указание с помощью
точечной нотации на узел reviews, а затем на все узлы review, которые
будут формировать ряды таблицы.
В DataGrid все элементы DataGridColumn создают колонки, в которых атрибут dataField указывает на дочерний узел узла review.
<mx:TextArea x="40" y="245" width="800" htmlText="{dgReviews.selectedItem.text}" />
Текстовое поле отображает описание выбранного в DataGrid элемента.
Чтобы быть уверенным в отправке запроса, добавляем в mx:Application:
creationComplete="reviewRequest.send()"
Запускаем Flex приложение (нажимем зеленую кнопку Run).
Результат показан на рисунке:

Теперь нам необходимо получить данные от Flex. Rails 1.1 делает это легко. Начнем с Flex. Добавим следующий код в MXML файл:
<mx:HTTPService contentType="application/xml" id="reviewCreateRequest" url="http://localhost:3000/reviews/create" useProxy="false" method="POST">
<mx:request xmlns="">
<review>
<title>{fTitle.text}</title>
<author>{fAuthor.text}</author>
<score>{fScore.text}</score>
<text>{fText.text}</text>
</review>
</mx:request>
</mx:HTTPService>
<mx:Form x="40" y="300" width="800">
<mx:Grid>
<mx:GridRow>
<mx:GridItem>
<mx:Label text="Title"/>
</mx:GridItem>
<mx:GridItem>
<mx:TextInput width="260" id="fTitle"/>
</mx:GridItem>
</mx:GridRow>
<mx:GridRow>
<mx:GridItem>
<mx:Label text="Author"/>
</mx:GridItem>
<mx:GridItem>
<mx:TextInput width="140" id="fAuthor"/>
</mx:GridItem>
</mx:GridRow>
<mx:GridRow>
<mx:GridItem>
<mx:Label text="Score"/>
</mx:GridItem>
<mx:GridItem>
<mx:TextInput width="20" id="fScore"/>
</mx:GridItem>
</mx:GridRow>
<mx:GridRow>
<mx:GridItem>
<mx:Label text="Text"/>
</mx:GridItem>
<mx:GridItem>
<mx:TextArea width="600" height="200" id="fText"/>
</mx:GridItem>
</mx:GridRow>
<mx:GridRow>
<mx:GridItem>
<mx:Button label="Submit" click="reviewCreateRequest.send();reviewRequest.send()"/>
</mx:GridItem>
<mx:GridItem>
</mx:GridItem>
</mx:GridRow>
</mx:Grid>
</mx:Form>
При этом добавляются два элемента в приложение: форма и новый HTTPService. Форма – это просто несколько полей и кнопка, вызывающая отправку данных в новый HTTPService.
<mx:HTTPService contentType="application/xml" id="reviewCreateRequest" url="http://localhost:3000/review/create" useProxy="false" method="POST">
<mx:request xmlns="">
<review>
<title>{fTitle.text}</title>
<author>{fAuthor.text}</author>
<score>{fScore.text}</score>
<text>{fText.text}</text>
</review>
</mx:request>
</mx:HTTPService>
Сервис использует метод POST для отправки XML в действие Rails
create. XML сформирован в запросе и заменен значениями из формы.
Заметьте, что задание contentType="application/xml" очень важно и
означает, что Flex отправляет содержимое типа XML в Rails.
Для Rails приложения добавляем новое действие в ReviewsController:
def create
@review = Review.new(params[:review])
@review.save
render :xml => @review.to_xml
end
Вот и все! Rails 1.1 получает запрос типа application/xml и
трансформирует его в вид, который может быть легко загружен в модель.
Затем oн сохраняется в базе данных, а нам ничего не возвращается.
При запуске Flex приложения мы получаем следующее:


Если вы введете данные в форму и отправите запрос, то они будут
добавлены в базу данных, и список обновиться. Это гибкий (Flexible)
скаффолдинг.
Ruby On Rails – это могучий бэкэнд для Flex приложений. А с новыми REST XML функциями Rails 1.1 стало очень легко делать XML запросы для Flash. А с помощью Flex их легко получать.