Mostrando postagens com marcador Rails. Mostrar todas as postagens
Mostrando postagens com marcador Rails. Mostrar todas as postagens

segunda-feira, dezembro 17, 2007

Chamadas Periódicas Sem Atropelo

Recentemente, precisei criar uma página que fazia chamadas periódicas ao servidor, para saber se um determinado processamento longo havia acabado, e carregar os resultados no caso positivo. No Rails, a melhor maneira de se fazer isso é com a função periodically_call_remote, que dispara uma chamada AJAX em intervalos regulares. Mas, aí, como é de praxe, encontrei um pequeno problema quando o código foi para o ambiente de integração. As chamadas são assíncronas (o primeiro A do AJAX), acontecendo a cada X segundos, mas a chamada que finalmente carregava os resultados demora mais de X segundos para ser completa. Então, no meio do carregamento, uma outra chamada era iniciada e terminava justo a tempo de substituir a maravilhosa tela de resultados pela tela de "por favor espere".

Tornar as chamadas síncronas resolvia este problema, mas fazia o browser congelar completamente nos n*X segundos que a resposta demorava para carregar. Então, a saída que eu acabei utilizando foi criar uma variável de "estado", manipulada pelos callbacks do Prototype, para garantir que apenas uma chamada assíncrona executasse por vez.

Este é o resultado:



<script>
var stop_polling = false;
var polling = false;
</script>
<%= periodically_call_remote(
:url => ping_search_search_results_url(@search),
:method => :get,
:frequency => 3,
:condition => "stop_polling == false && polling == false",
:after => "polling = true",
:complete => "polling = false"
) %>


A primeira variável ("stop_polling") tem seu valor mudado pelo servidor quando os resultados ficam prontos. A segunda é alterara pelo próprio script para impedir que uma nova chamada seja executada enquanto a anterior ainda está esperando sua resposta. Com isso, o browser do usuário não congela.

terça-feira, novembro 20, 2007

Alterando Plugins de Rails - O Método do "Gêmeo Maligno"

Uma das coisas boas do Rails é o sistema de plugins, que permite aumentar a funcionalidade do framework de várias maneiras. Mas existe um problema bem comum associado a ele: muitas vezes um determinado plugin quase faz aquilo que você quer, então você precisa alterá-lo para que ele se adapte melhor. Como fazer isso?

Este artigo do Err the blog mostra um método bastante interessante.

segunda-feira, novembro 12, 2007

Pegadinhas do Internet Explorer

Eu ia escrever "Internet Exploder", mas aí ia ficar mais difícil achar o post através de buscas...

Pegadinha 1: Cabeçalhos de tabela são protegidos contra alteração. Portanto, páginas com AJAX que como um de seus efeitos alterem cabeçalhos de tabela não vão funcionar no IE. Use um "div" no lugar apropriado ao invés de mexer com os cabeçalhos.

Pegadinha 2: No IE, a função Javascript "window.open" sempre deve ter o nome da janela. E esse nome não deve conter espaços. Os outros browsers aceitam isso na boa, mas o IE não.

terça-feira, junho 26, 2007

"Auto-complete" Avançado em Rails

Atenção! Nerdice avançada abaixo! Este post discute como implementar campos com "auto-complete" avançado em Rails. Se você não tem a mínima idéia do que seja um "auto-complete" básico, recomendo que leia este tutorial.

O Rails vêm com duas bibliotecas de Javascript para facilitar a implementação de interfaces AJAX em suas aplicações: a Prototype (para requisições assíncronas básicas) e a Script.aculo.us para "efeitos especiais".

Um dos efeitos especiais mais apreciados pelo usuário é o tal "auto-complete", onde ele começa a digitar algo em um campo de texto e vê, magicamente, um menu aparecer logo abaixo com várias alternativas que ele pode escolher com o mouse ou as setas do teclado, fazendo com que o valor do campo seja completado automaticamente com a opção escolhida. De acordo com o Agile Web Development with Rails, a reação inicial do usuário ao usar isso pela primeira vez é algo entre surpresa e admiração. O mesmo livro explica como usar os helpers do Rails para implementar o efeito.

Os helpers ajudam mesmo, mas como tudo no Rails eles cuidam apenas do caso mais comum. Fazer algo mais complexo vai tomar alguns minutos do seu tempo.

Por exemplo, ontem eu precisei de um "auto-complete" que preenchia vários campos da mesma página, ao invés de apenas um. Basicamente, o usuário escolhia o nome de um objeto, e os campos eram preenchidos com informações desse objeto. Eis como isso foi feito:

Um dos elementos de um auto-complete básico, como pode ser visto nos bons tutoriais on-line, é um partial contendo o template para o fragmento de HTML retornado pela chamada ao auto-complete (normalmente a lista de nomes). Ele se parece com algo do tipo:

<ul>
<% @objects.each do |object| %>
<li><%= object.name %></li>
</ul>


A primeira coisa a fazer é alterar o fragmento acima para que retorne os demais atributos dos quais precisamos, mas que ainda assim só mostre o nome para o usuário.

<ul>
<% @objects.each do |object| %>
<li>
<span><%= object.name %></span>
<span class="hidden"><%= object.outro_atributo %></span>
<span class="hidden"><%= object.e_mais_outro %></span>
...
</li>
</ul>




Na sua folha de estilo, você coloca algo do tipo "span.hidden { display: none }" , fazendo com que os attributos marcados como hidden acima não apareçam.

E, para finalizar, inclua o método abaixo entre seus helpers customizados:


def custom_auto_complete( field_id, div_id, url, fields )
assignments = []
fields.each_with_index do |field, i|
assignments << "$('#{field}').value = dn[#{i}].firstChild.nodeValue;"
end
<<-END
<script type="text/javascript">
new Ajax.Autocompleter( '#{field_id}',
'#{div_id}',
'#{url_for( url )}',
{ updateElement: function( selected ) {
Element.cleanWhitespace( selected );
dn = selected.childNodes;
#{assignments.join("\n")}
}
} );
</script>
END
end



O método acima funciona de maneira parecida com o helper padrão, apesar de aceitar uma variedade menor de parâmetros. O que ele faz é gerar um bloco de Javascript que cuida das funções de auto-complete avançadas. Os parâmetros que ele deve receber são:

field_id - o identificador (valor do atributo "id") do campo "primário", ou seja, aquele em que o usuário digita as informações.
div_id - o identificador do "div" que vai mostrar as opções.
url - um hash do tipo que se passa ao método url_for, com a URL da qual serão recuperadas as opções.
fields - um array contendo os mesmos nomes dos campos colocados no partial acima, na mesma ordem.

Basta usar o helper acima na hora de implementar o "auto-complete" avançado:

<%= custom_auto_complete(...) %>

segunda-feira, junho 25, 2007

Coisas Importantes para se Saber ao Aprender Ruby on Rails

Uma lista bem interessante de coisas básicas que todo programador que quer trabalhar com Ruby on Rails deve saber.

sábado, junho 02, 2007

Authorization para Rails

Um framework de autorização é algo complementar ao conhecido esquema de login/senha. Ele controla o que o usuário pode fazer depois que entra no site, o que é muito útil quando se quer construir sites ao estilo do Orkut ou do Google Documents, onde um usuário pode permitir que outros vejam os seus dados, ou restringir esse acesso a um grupo seleto de pessoas.

Eu já havia trabalhado com um framework de autorização nos meus dias de Java (ou seja, até a uma semana atrás), e na minha opinião ele era a pŕopria definição da palavra entreprisey: dá-lhe EJBs, arquivos de configuração XML e códigos abstrusos para indicar as permissões, tudo isso embrulhado em um conjunto de /[WEJ]ARs/ cujo empacotamento correto era uma ciência mais cheia de minúcias que qualquer engenharia aeronáutica.

O plugin Authorization, para o Rails, a princípio me deu um pouco de medo, por causa dessa experiência anterior. Então, quando me pediram para integrá-lo a um determinado projeto, eu me assustei e dei um prazo de três dias, imaginando que os primeiros dois seriam para entender como ele funciona e o terceiro para implementá-lo. Tudo isso, é claro, supondo um mínimo de 8 horas por dia de trabalho sem interrupções.

Fiz tudo em duas horas. "Tudo" incluiu alterar o modelo de banco de dados do projeto para comportar a tabela de permissões do plugin. Ainda não consegui juntar o queixo do chão...

Tenho certeza de que o Authorization possui suas próprias dificuldades, mas de alguma forma eu não acho que elas sejam tão grandes quanto a desse framework Java sem nome. Tenho certeza também que existe uma grande quantidade de frameworks de autorização maravilhosos para Java, e gostaria de ouvir exemplos.

sexta-feira, junho 01, 2007

YAML é sensível a espaços

Cá estava eu sendo um produtivo cidadão da sociedade mundial, quando me deparo como seguinte erro ao executar o comando rake db:migrate:

'yntax error on line 18, col 2: ` host: localhost


O que diabos isso quer dizer? Bom, depois de pesquisar um pouco descobri este post, que me informou que o YAML ( a linguagem utilizada na configuração do banco de dados no Rails) é sensível a espaços. Uma das linhas do meu arquivo database.yml era:

password:xxxxx

quando deveria ser

password: xxxxx

Note que a mensagem de erro não teve absolutamente nada à ver com o erro de verdade! A linha host: localhost era a que vinha logo acima no arquivo, o que me faz supor que o sistema pensou que a linha de baixo era uma continuação da de cima.

Este post é bem mais técnico do que a média aqui. Espere mais deles, pois agora eu não tenho mais acesso a blogs corporativos internos.