RIA, É o melhor remédio!

Flex / Flex Builder, Flex Builder, Ruby on Rails No Comments »

Desde que a Internet apareceu em minha vida, ainda com o nome de BBS, venho estudando e me aprimorando desde então, já estudei muitos assuntos dentro da minha área, mas nunca ri tanto, quando conheci o Flex 2, já tinha instalado uma vez, mas a primeira vez que instalei, não consegui nem executá-lo (era o SDK).

Desisti! Depois de algum tempo, estudando na FGG (Faculdade Gratuita Google) o professor Search me apresentou o Flex 2 Builder, baixei alguns tutoriais, e comecei a bricar com ele, simplesmente apaixonante.

Minha satisfação então se completou quando conheci o curso de Flex on Rails que o Carlos Eduardo iria ministrar através do Treina TOM. Foi através dele que conheci mais ainda o poder do Flex.

Essa semana recebi um e-mail, curso de Flex pela e-Genial, só felicidade, com certeza serei uns dos primeiros a me inscrever. Quero ter um domínio completo sobre o Flex, e não perderia por nada um curso de Flex ministrado nada mais, nada menos por Fábio Terracini, um dos pioneiros com desenvolvimento em Flex no Brasil.

É claro, não poderia deixar de agradecer o meu amigo Carlos Eduardo por ser um dos principais, senão o mais, a contribuir para o crescimento da RIA aqui no Brasil.

RIA, faz bem pros olhos!

DBModelGem

Ruby on Rails No Comments »

O dbmodel gem aceita arquivos de modelo de dados de XML, chama generate model ou generate scaffold para tabelas com relacionamento, e insere relações (“has_many :beers”) em arquivos Model apropriado. A inserção de relacionamento em arquivos Model são arquivos existentes não destrutivos não são removidos e o código atual é mantido

Instalação:

Baixe DBDesigner 4.0. (O Workbench sucessor será lançado este ano) Carregue e instale

gem install dbmodel-0.1.0.gem –rdoc

O gem patch se você não estiver no Windows para lidar com caminhos corretamente. Brian Bugh forneceu o seguinte patch:

91c91
< modelfile = File.dirname(xmlfile) + File.join(”, ‘..’, ‘app’, ‘models’, table[’name’].singularize + ‘.rb’) — > modelfile = File.dirname(xmlfile) + ‘\..\app\models\\’ + table[’name’].singularize + ‘.rb’ 265c265 < require File.dirname(f) + File.join(”, ‘..’, ‘config’, ‘environment’) # Better way to do this? — > require File.dirname(f) + ‘/../config/environment’ # Better way to do this? 283c283 < if ex.message =~ /config#{File::SEPARATOR}environment/ — > if ex.message =~ /config\/environment/

Como usar:

Use DBDesigner para construir tabelas e especificar relações entre as mesmas. Etiquete as relações de maneira que o Rails compreenda, como has_many :cervejas ou has_and_belongs_to_many :coisas. Como o tempo você pode usar habtm :X em vez de has_and_belongs_to_many :X. Nota que você nunca precisará etiquetar um link belongs_to — relacionamento são definidos do ponto de vista da tabela, então o belongs_to é implícito na relação.
Salve seu modelo em um arquivo DBDesigner XML em sua pasta app/db. Então use o comando:

dbmodel mymodel.xml

Este gerará arquivos de modelo para todas as tabelas com relacionamento. Você pode escolher scaffolding por embedding tags dentro de seus comentários de tabelas.

Tradução do site: http://wiki.rubyonrails.com/rails/pages/DBModelGem

Chave Primária Composta

Ruby on Rails No Comments »

Porque

O RubyonRails não suporta chaves primárias compostas. Este software livre é uma extensão para a camada de banco de dados Rails – ActiveRecords – para aceitar chaves primárias compostas tão transparentemente quanto possível.
Qualquer script de Rubi usando ActiveRecords pode usar Chaves Primárias Composto com esta biblioteca.

Instalando

sudo gem install composite_primary_keys

Rails: Adicione a seguinte linha na parte inferior de seu environment.rb

require 'composite_primary_keys'

Script Ruby: Adicione a seguinte linha no topo de seu script

require 'rubygems'
require 'composite_primary_keys'

O Básico

Um modelo com chaves primárias compostas pareceria com …

class Membership < ActiveRecord::Base
  # set_primary_keys *keys - turns on composite key functionality
  set_primary_keys :user_id, :group_id
  belongs_to :user
  belongs_to :group
  has_many :statuses, :class => 'MembershipStatus', :foreign_key => [:user_id, :group_id]
end

Um modelo associado com um modelo de chave composto seria definido como …

class MembershipStatus < ActiveRecord::Base
  belongs_to :membership, :foreign_key => [:user_id, :group_id]
end

Isto é, associações podem incluir chaves compostas também. Bom.

Demonstração de Uso

Uma vez que você tem criados seus modelos para especificar chaves primárias compostas (como a classe Membership) e associações (como MembershipStatus#membership), você pode usar-las como qualquer modelo normal com associações.
Mas primeiro, verifique nossas chaves primárias.

MembershipStatus.primary_key # => "id"    # Chave Normal
Membership.primary_key  # => [:user_id, :group_id] # Chave composta
Membership.primary_key.to_s # => "user_id,group_id"

Agora nós queremos achar instâncias usando a mesma sintaxe que nós sempre usamos para ActiveRecords …

MembershipStatus.find(1)    # single id returns single instance
=> <MembershipStatus:0x392a8c8 @attributes={"id"=>"1", "status"=>"Active"}>
Membership.find(1,1)  # composite ids returns single instance
=> <Membership:0x39218b0 @attributes={"user_id"=>"1", "group_id"=>"1"}>

Usando Ruby on Rails? Você desejará seu seu helpers url_for para converter chaves compostas em strings e voltar novamente …

Membership.find(:first).to_param # => "1,1"

E então use a string ID dentro de seu controlador para achar o objeto novamente

params[:id] # => '1,1'
Membership.find(params[:id])
=> <Membership:0x3904288 @attributes={"user_id"=>"1", "group_id"=>"1"}>

Isto é, um ActiveRecord sustentando chaves compostas se comporta transparentemente ao longo de sua aplicação. Só como um ActiveRecord normal.

Outros Truques

Passe por uma lista de id composto para o achar método

Membership.find [1,1], [2,1]
=> [
  <Membership:0x394ade8 @attributes={"user_id"=>"1", "group_id"=>"1"}>,
  <Membership:0x394ada0 @attributes={"user_id"=>"2", "group_id"=>"1"}>
]

Perform #count operations

MembershipStatus.find(:first).memberships.count # => 1

Rotas com Rails

De Pete Sumskas:
Eu choquei-me com um problema que eu não vi mencionado nesta lista – e eu não vi quaisquer informações sobre ele na documentação de como eu devia fazer para trata-lo. O problema era que os URLs sendo gerado para ação do show (por exemplo) teve uma sintaxe como:
/controller/show/123000,Bu70
Para um PK de dois campos composto. A rota padrão não combinaria, então depois de descobrir como fazer a rota que eu adicionei:

  Map.connect ':controller/:action/:id ', :iD => /w+(,w+)*/

ao meu arquivo route.rb.

Que Banco de Dados?

Um suíte de testes da unidade foi executado nos bancos de dados seguintes sustentado por ActiveRecord:

Database

Sucesso do Teste

Retorno (since 0.8.0)

mysql YES ??? (Yes! or No…)
sqlite3 YES (new 0.8.0) ??? (Yes! or No…)
postgresql YES (new 0.8.0) ??? (Yes! or No…)
oracle YES (new 0.8.2) YES (Yes! or No…)
sqlserver ??? (I can help) ??? (Yes! or No…)
db2 ??? (I can help) ??? (Yes! or No…)
firebird ??? (I can help) ??? (Yes! or No…)
sybase ??? (I can help) ??? (Yes! or No…)
openbase ??? (I can help) ??? (Yes! or No…)
frontbase ??? (I can help) ??? (Yes! or No…)

Class ActionController::Base

Ruby on Rails No Comments »

Os controladores de ação são o centro de um pedido da web em Rails. Eles são compostos de uma ou mais ações que são executadas em pedido e então ou  num template ou redireciona para outra ação. Uma ação é definida como um método público no controlador, que estará automaticamente acessível para a web-server por Rails Routes.

Um simples controlador pode parecer com isto:

 class  GuestBookController < ActionController::Base
      def index
        @entries = Entry.find(:all)
      end

    def sign
        Entry.create(params[:entry])
        redirect_to :action =>  "index"
      end
    end

Actions, por padrão,  um modelo no diretório app/views correspondendo ao nome do controlador e ação depois de executar código na ação. Por exemplo, a ação index do GuestBookController iria  o modelo app/views/guestbook/index.rhtml por padrão depois de povoar a variável de instância @entries.
Diferentemente de index, a ação não sinalizará um modelo. Depois de apresentar seu propósito principal (criando uma nova entrada no Guest Book), inicia um redirecionamento. Este redireciona trabalhos retornando uma resposta externa "302 Moved" HTTP que leva o usuário para a ação index.
O index e sinal representam os dois arquétipos de ação básica usados em Controladores de Ação. Get-and-show e do-and-redirect. A maioria das ações são variações destes temas

Request

Request são processados pelo framework Action Controlador extraindo o valor da "chave de ação nos parâmetros request. Este valor devia segurar o nome da ação para ser apresentado. Uma vez que a ação foi identificada, os parâmetros request restante, a sessão (se uma está disponível), e o full request com todos os cabeçalhos HTTP ficam disponíveis para a ação por variáveis de instância. Então a ação é apresentada.
O objeto request está disponível com o request accessor e é principalmente usado por query para cabeçalhos HTTP. Estas queries são feitas acessando o hash de ambiente, como isto:

  def server_ip
    location = request.env["SERVER_ADDR"]
    render :text => "This server hosted at #{location}"
  end

Parameters

Todos os parâmetros request, se eles vêm de um GET ou POST request, ou do URL, estão disponíveis pelo método params que retorna um hash. Por exemplo, uma ação que era apresentada /weblog/list?category=All&limit=5 incluirá { "category" => "All", "limit" => 5 } em params.
É também possível construir hash de parâmetro dimensionais múltiplo especificando chaves usando parênteses, como:

  <input type="text" name="post[name]" value="david">
  <input type="text" name="post[address]" value="hyacintvej">

Um pedido originando-se de um form possuindo estas entradas incluirão { "post" => { "name" => "david", "address" => "hyacintvej" } }. Se a entrada de endereço foi nomeada "post[address][street]", O params teria incluído { "post" => { "address" => { "street" => "hyacintvej" } } }. Não há nenhum limite para a profundidade do alinhamento.

Sessions

As sessões permite que você armazene objetos entre pedidos. Isto é útil para objetos que não estão ainda prontos para ser persistidos, como objeto de Signup construido em um processo multi-paged, ou objetos que não muda muitos e são necessários o tempo todo, como objeto de Usuário para um sistema que exige login. A sessão não devia ser usada, porém, como um cache para objetos onde ele provavelmente podiam ser mudados. Ele normalmente trabalha demais para manter isso tudo sincronizados.
Você pode colocar objetos na sessão usando o método de sessão, que acessa um hash:

  session[:person] = Person.authenticate(user_name, password)

E recuperado novamente pelo mesmo hash:

  Hello #{session[:person]}

Para remover objetos da sessão, você pode remover qualquer um atribuindo uma chave única para NIL, como session[:person] = nil, ou você pode remover a sessão inteira com reset_session.
Por padrão, Seções são armazenadas no sistema de arquivo em RAILS_ROOT/tmp/sessions. Qualquer objeto pode ser colocado na sessão (desde que ele possa ser Disposto). Mas lembre que 1000 sessões ativas cada uma armazena um objeto de 50kb pode levar uma loja de 50MB no filesystem. Em outras palavras, pense cuidadosamente sobre tamanho e caching antes de recorrer para o uso da session no filesystem.
Uma alternativa para armazenar seções em disco é usar ActiveRecordStore para armazenar seções em seu banco de dados, que pode resolver problemas causados por armazenando de seções no sistema de arquivo e poder acelerar sua aplicação. Para usar ActiveRecordStore, descomente a linha:

  config.action_controller.session_store = :active_record_store

no seu environment.rb e execute o rake db:sessions:create.

Responses

Cada ação resulta em uma resposta, que possui os cabeçalhos e documentos para serem enviadas para o navegador usuário. O objeto de resposta real é automaticamente gerado pelo uso de renders e redireciona e não exige nenhuma intervenção de usuário.

Renders

O controlador de ação envia conteúdo para o usuário usando um de cinco métodos de renderização. A mais versátil e comum ser a renderização de um modelo. Incluído no Action Pack no Action View, que habilita renderização de modelos de ERb. Ele é automaticamente configurado. O controlador passa por objetos para a visão atribuindo variáveis de instância:

  def show
    @post = Post.find(params[:id])
  end

Que são então automaticamente disponível para a visão:

  Title: <%= @post.title %>

Você não tem que contar com a retribuição automatizada. Especialmente ações que podiam resultar na renderização de modelos diferentes usarão os métodos de renderização manual:

  def search
    @results = Search.find(params[:query])
    case @results
      when 0 then render :action => "no_results"
      when 1 then render :action => "show"
      when 2..10 then render :action => "show_many"
    end
  end

Leia mais sobre escrever ERb e construir templates em classes/ActionView/Base.html.

Redirects

Redirects são usados para mover de uma ação até outra. Por exemplo, depois da ação create, que armazena uma entrada de blog para um banco de dados, nós poderíamos mostrar ao usuário a nova entrada. Porque nós seguimos os princípios DRY (Don‘t Repeat Yourself), nós vamos reusar (e redirecionar para) uma ação de show que presumimos já ter sido criado. O código poderia parecer com isto:

  def create
    @entry = Entry.new(params[:entry])
    if @entry.save
      # The entry was saved correctly, redirect to show
      redirect_to :action => 'show', :id => @entry.id
    else
      # things didn't go so well, do something else
    end
  end

Neste caso, depois de salvar nossa nova entrada para o banco de dados, o usuário é redirecionado para o método show que é então executado.

Chamando múltiplos redirects ou renders

Uma ação devia concluir com um único render ou redirect. Tentando fazer qualquer um novamente resultará em um DoubleRenderError:

  def do_something
    redirect_to :action => "elsewhere"
    render :action => "overthere" # raises DoubleRenderError
  end

Se você precisar redirecionar na condição de algo, então não deixe de adicionar "and return" para parar a execução.

  def do_something
     redirect_to(:action => "elsewhere") and return if monkeys.nil?
     render :action => "overthere" # won’t be called unless monkeys is nil
   end

Active Record

Ruby on Rails No Comments »

Active Record

Enquanto eu trabalhava em uma parte de meu livro, eu mesmo achei em ./script/console e estava vendo alguns assuntos misteriosos quando eu usaria has_many e belongs_to.
Vamos ver dois modelos simples.

 

class Order < ActiveRecord::Base 
    belongs_to :customer 
  end 
class Customer < ActiveRecord::Base 
    has_many :orders 
  end 

Depois de alguns testes de registros

test_dev=# SELECT * FROM  customers;  
 id |      name      
  —-+—————- 
  1 | Robby 
  2 | Nigel 
  3 | Linus 
(3 rows) 
test_dev=# SELECT * FROM orders; 
   id | customer_id | amount 
  —-+————-+——– 
    1 |           1 |   12.00 
    2 |           3 |   12.00 
  (2 rows) 

Nada completamente louco continuando, certo?

<typo:code lang="ruby"> 
  Loading development environment. 
  >> Customer.destroy(3) 
  => {"name"=>"Linus", "id"=>"3"} 
  >>     

=# SELECT * FROM orders; 
   id | customer_id | amount 
  —-+————-+——– 
    1 |           1 |   12.00 
    3 |           3 |   12.00 
  (2 rows)

Espere um minuto! Eu só apago um cliente com um iD de 3!

Então, o que está errado com este argumento? Você pode pensar sobre alguns problemas potenciais que podiam acontecer de dados como isto? O registro tem um customer_id para um cliente que não existe. Isto é por que nós temos bancos de dados relacional em primeiro lugar, certo? :-)

Aqui está algo que eu aprendi hoje que eu sabia. O registro ativo permite que você passe pela declaração has_method a opção :dependent.

class Customer < ActiveRecord::Base 
  has_many :orders, :dependent => true 
end

O que é esta opção? Bem, de acordo com a documentação de AR, “:dependent – se fixado para true todo o objeto associado são destruídos ao lado deste objeto. Não pode ser fixado se :exclusively_dependent também está fixado.”
Em um nutshell, este trabalho ON DELETE CASCADE como é feito em PostgreSQL. Então, irá apagar as ordens associadas com o cliente que eu estava tentando destruir.
Até hoje, eu não tenho o hábito de usar o built-in constraints/triggers do PostgreSQL. Então, assim que eu fiz, este assunto surgiu e eu aprendi sobre :dependente.

test_dev# d orders
                                Table  "public.orders" 
    Column    |     Type       |                       Modifiers                        
————-+—————+————————————————
 id           | integer       | not null default 
 customer_id | integer       | nextval(’public.orders_id_seq’::text)
 amount       | numeric(10,2) | 

Indexes:
       "orders_pkey" PRIMARY KEY, btree (id)
  Foreign-key constraints:
       "orders_customer_id_fkey" FOREIGN KEY (customer_id) REFERENCES  customers(id)

test_dev=# ALTER TABLE orders DROP  CONSTRAINT orders_customer_id_fkey;
  ALTER TABLE 

RobbyOnRails:~/Programming/footest  robbyrussell$ ./script/console 
  Loading development environment.
  >> cust = Customer.create(:name  => ‘Jim’)
  => #<Customer:0×275373c  @new_record_before_save=true, @new_record=false,  @attributes={"name"=>"Jim", "id"=>5},  @errors=#<ActiveRecord::Errors:0×274fa88 @base=#<Customer:0×275373c  …>, @errors={}>>
  >> cust.orders.create(:amount  => ‘25.00′)
  => #<Order:0×274991c  @new_record=false, @attributes={"id"=>4,  "amount"=>"25.00", "customer_id"=>5},  @errors=#<ActiveRecord::Errors:0×2746dfc @base=#<Order:0×274991c …>,  @errors={}>>
  >>                

test_dev=# SELECT * FROM orders;
   id | customer_id | amount 
  —-+————-+——–
     1 |           1 |  12.00
     3 |           4 |  29.00
     4 |           5 |  25.00
  (3 rows)

Como você pode ver, eu mesmo coloco nas mãos Active Record quando eu executei o DROP CONSTRAINT. Então eu tentei executar o código no topo do post… e não funcionou.
De acordo com o docs, se você usar :dependent => true, devia apagar os registros da tabela estrangeira. Se não, devia fixar o valor do campo foriegn key para NULL na tabela estrangeira.
Basicamente, apresento estas duas queries SQL:

UPDATE orders SET customer_id = NULL  WHERE customer_id = 17; 

DELETE FROM customers  WHERE id = 17;

Então, os registros ainda estão no banco de dados para aquelas ordens, mas o cliente é excluído. Existem argumentos para e contra fazer este tipo de coisa… mas a habilidade de ter a opção é sempre boa. Em todo caso, Active Record não executaria a primeira query, ela está só excluindo da tabela clientes. Sem minha restrição, nenhum erro seria retornado do PostgreSQL e eu comecei a ter alguns dados ruins.
Imagine mostrar uma lista de pedidos e tentar exibir o nome do cliente associado com um pedido que não tem nenhum cliente linkado. Doh! Se o Active Record fixou o customer_id para NULO nós podemos pelo menos ter um pouco de lógica para trabalhar com ele sem ter que executar algumas queris de SQL para compreender que ordens tem e não tem clientes. (Nós queremos nossas aplicações com dados limpos!)
De qualquer maneira… Isto era um bug? O Active Record deve saber atualizar os registros para NULO neste caso? Eu figurei isto é devia ser manipulado esta tarefa, especialmente desde que era manipulado exclusão em cascata quando você passa :dependent como true.
Porém, eu prematuramente não quis postar um relatório de bug, então eu comecei a perguntar ao redor em #rubyonrails (irc.freenode.net). Pessoas fizeram um grupo de sugestões de como trabalhar com isto. Eu podia adicionar um método before_destroy em meu modelo, persiga o bug, (re)adicionei um gatilho ON DELETE à minha tabela (hah), etc. Aproximadamente, eu decidi que eu veria se eu pudesse perseguir o que acontece quando has_many for usado para um modelo em #destroy.
Depois de fazer alguns testes, eu postei um patch e um relatório de bug. (Por favor desconsidere meu primeiro patch… que não funcionou! Heh)
Agora que eu figurei este, eu estou indo contente adiciona minhas restrições atrás das minhas tabelas e volta a namorar. Este me lembrou de um post que eu tive alguns meses atrás quando eu mencionei que eu pensei que era melhor pôr algumas restrições e lógica no banco de dados. Eu também concordo que aquelas restrições deviam ser colocadas na camada de abstração, mas nós não podemos sempre pôr toda fé em nosso código, qualquer um. Alguns níveis de cheques não machuca. :-)
Isto era uma diversão pequena enigma que eu empreendi hoje. A moral da história? Se você tiver a habilidade de usar o builtin referential integrity do PostgreSQL e aqueles outros bancos de dados, poderia ser uma boa idéia fazer isso. As coisas são omitidas, pessoas logan para o banco de dados de muitas formas, e de programas diferentes.
ATUALIZAÇÃO: DHH respondeu para este post e forneceu um link que discute Banco de dados de Aplicação contra Banco de dados Integrado
Devia ser notado que existe uma distinção importante entre os dois métodos. Quando eu disse, “Coisas são omitidas, pessoas logan para o banco de dados de muitas formas, e de programas diferentes” eu basicamente estava descrevendo Banco de dados de Integração. Porém, eu também estava pensando sobre a possibilidade de alguém abrir seu GUI de MySQL ou PostgreSQL e manualmente removendo um registro em SQL claro. De acordo com o Banco de dados de Aplicação, no momento que você faz isto, você basicamente quebra este modelo e não pode esperar que sua aplicação seja completamente responsável pelos problemas que podem ou não podem acontecer. Neste momento, você precisaria olhar para sua aplicação em termos de Banco de dados de Integração. Por favor me corrija se eu estiver errado. :-)
Porém, com este argumento, minha primeira tentativa para mover para contar com AR teve uma solução secundário, mas ele era um fix fácil.
Apresentando o comando seguinte, eu estou movendo para um padrão de Banco de dados de Integração e isso devia ser reconhecido quando levando esta em consideração.

ALTER TABLE orders ADD CONSTRAINT  orders_customers_id_fkey 
     FOREIGN KEY (customer_id) REFERENCES customers (id) MATCH FULL; 

Ok, volte ao trabalho!
Uma vez mais. Use restrições! (Se você pode)… E graças ao DHH para fornecer o link e me motivando a fazer uma nota desta em minha entrada.
Tradução do Post colocado no site www.robbyonrails.com por Robby Russell

Criando um leitor de RSS Feed - Parte II

Ruby on Rails No Comments »

Inserindo um componente HTTPService

Para o leitor de blog nesta lição, você recuperará posts do blog do Matt Chotin em http://weblogs.macromedia.com/mchotin/index.xml em um agregador de notícias de um site da web. Matt é um gerente de produto na equipe Flex e escreve sobre Flex em seu blog.

Você pode usar o componente HTTPService para acessar o XML que alimenta e recupera informações sobre posts recentes. O componente permite que você envie um pedido HTTP GET ou POST, e então recupere os dados retornados na resposta.

  1. No modo Source , entre com a seguinte tag <mx:HTTPService> imediatamente depois da tag aberta<mx:Application>:

    <mx:HTTPService    id=”feedRequest”    url=”http://weblogs.macromedia.com/mchotin/index.xml”    useProxy=”false”/>

    A propriedade URL especifica o local do arquivo solicitado, neste caso o feed RSS 2.0 do blog do Matt Chotin. Quando esse tutorial foi escrito, o URL ainda estava era válido, mas você devia verificar e ter certeza que ele não mudou. Você deve usar o RSS mais recente 2.0 listado à direita do blog em http://www.adobe.com/go/mchotinblog.

    NOTA
    Se você quiser, poderá usar o seguinte alias no componente: http://www.adobe.com/go/flex_blogfeed.

    A propriedade useProxy especifica que você não quer usar um proxy em um servidor. O domínio onde o blog do Matt está localizado tem uma instalação crossdomain.xml, então o flash player pode acessar as fontes de dados remotas neste servidor, inclusive RSS feeds.

    O próximo passo é iniciar o aplicativo para enviar um pedido para o URL especificado. Você decide enviar o pedido automaticamente sempre que o aplicativo começa, como segue.

  2. Na tag <mx:Application>, adicione a seguinte propriedade creationComplete (in bold):

    <mx:Application xmlns:mx=http://www.adobe.com/2006/mxmllayout=”absolute” creationComplete=”feedRequest.send()” >
  3. Quando seu aplicativo terminar de carregar, o componente HTTPService chama o método send(). O método faz um pedido HTTP GET ou POST para o URL especificado, e uma resposta de HTTP é retornada. Neste caso, o RSS feerd retorna dados XML.

    Próximo, você quer verificar se o aplicativo está recuperando o RSS feed com sucesso. Você pode fazer isto no controle de tag, como segue.

  4. Na tag <mx:Panel>, renomeie o valor da propriedade title (”Blog Reader”) pela seguinte expressão(in bold):

    title=”{feedRequest.lastResult.rss.channel.title}

    Esta expressão liga o campo título para o controle de Painel. A expressão reflete a estrutura do XML. Quando XML é retornado a um componente HTTPService, o componente analisa gramaticalmente isto em um objeto de ActionScript chamado lastResult. A estrutura do objeto lastResult reflete a estrutura do XML. Para verificar a estrutura do XML, carregue o arquivo XML RSS feed ( http://www.adobe.com/go/flex_blogfeed) e abra-o no navegador.

    A estrutura geral do XML é a seguinte:

    <rss>    <channel>        <title>        other child nodes of <channel>        <item>            <title>            other child nodes of <item>        </item>        …

    Alguns nodos têm nodos filhos contendo dados, inclusive o nodo “title” é um nodo filho de channel. O lastResult do componente HTTPService (feedRequest.lastResult) reflete esta estrutura:

    feedRequest.lastResult.rss.channel.titleSeu código deve parecer com o exemplo seguinte:
    <?xml version=”1.0″ encoding=”utf-8″?><mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”    layout=”absolute”    creationComplete=”feedRequest.send()” >
    
        <mx:HTTPService        id=”feedRequest”        url=”http://weblogs.macromedia.com/mchotin/index.xml”        useProxy=”false” />
    
        <mx:Panel x=”10″ y=”10″ width=”475″ height=”400″ layout=”absolute”        title=”{feedRequest.lastResult.rss.channel.title}”>
    
            <mx:DataGrid x=”20″ y=”20″ id=”dgPosts” width=”400″>            <mx:columns>                <mx:DataGridColumn headerText=”Column 1″ dataField=”col1″/>                <mx:DataGridColumn headerText=”Column 2″ dataField=”col2″/>                <mx:DataGridColumn headerText=”Column 3″ dataField=”col3″/>            </mx:columns>        </mx:DataGrid>
    
            <mx:LinkButton x=”20″ y=”225″ label=”Read Full Post”/>        <mx:TextArea x=”20″ y=”175″ width=”400″/>    </mx:Panel>
    
    </mx:Application>
  5. Salve o arquivo, espere até que o Flex Builder termine de compilar o aplicativo, e então clique no botão Run na barra de ferramentas para iniciar o aplicativo. Se você estiver usando a configuração de plug-in do Flex, Selecione Run > Run As > Flex Application.

    Um Browser abrirá e executará o aplicativo. O título do blog, Matt Chotin, deve aparecer como o título do controle de Painel, indicando que o aplicativo com sucesso recuperou dados do RSS feed.

    NOTA
    Pode haver uma demora de alguns segundos antes do título aparecer enquanto o aplicativo está contactando o servidor.