Fork me on GitHub

Viagens, opiniões e afins

by Andre Fonseca


Mais uma do SOLR – Dynamic Fields

Como alguns que acompanham o blog já devem ter percebido, eu estou usando o SOLR em um projeto. O SOLR é um servidor Web de busca, feito em cima do Lucene (grupo Apache). Ele é realmente poderoso e simples de usar. Recomendo muito para quem precisa fazer buscar textuais pesados e que tem uma quantidade razoável de documentos/dados para indexar.  Como minha aplicação é Rails, estou usando uma GEM, chamada Sunspot, que serve de DSL (facilitador) nessa “conexão” entre minha app e o SOLR.

Nesse dias surgiu a necessidade de fazer uma nova feature em nosso sistema que parece ser bem simples mas como busco pelo SOLR a coisa ganhou bastante complexidade.Só para que entendam o problema, deixe me contextualizá-los.  Minha aplicação é uma ferramenta de seleção de pessoas – CASTING. Nela um administrador cria uma campanha e define um formulários com N perguntas que serão respondido pelo candidato. Ao finalizar o preenchimento, esse formulário vira um inscrições e salvamos suas respostas.  Surgiu então a necessidade de buscarmos por inscrições através de valores de respostas a perguntas específicas:  Quero buscar por todas as inscrições que responderam Vasco para a pergunta “Qual é o seu time do coração?”.

Muitos, se não considerarmos que estamos usando o SOLR e que vamos fazer essa pesquisa direto no banco de dados, vão dizer é a solução bem simples: Se resume a um query onde informo o campo e o valor de resposta desejado. Tendo isso busca pelas inscrições que tenha aquela resposta. Simples, não é? Nem tanto. O meu cliente deseja que isso esteja integrado aos demais filtros já existentes – idade, sexo, estado, status, etc.

Bem antes desse nova funcionalidade, a busca direto no banco, dado a quantidade de dados, já se mostrou inviável. Logo, sem chances de eu largar o SOLR e voltar para o banco ou tentar fazer algo híbrido.

Parte para tentar descobrir se existia algo dentro do universo do SOLR e/ou do Sunspot onde eu pudesse definir um campo do indice de forma dinâmica, ou seja, para cada instancia que for criando. Depois de um certo tempo gasto com o Oráculo (Google) , fiquei feliz que mais uma vez nem a gem nem o servidor me decepcionou.

O Sunspot tem um recurso que é o “dynamic field” que é o seguinte: todo o indice de sua classe é feito no build da classe, ou seja, no seu load.  Como precisava definir coisas que só existiriam no contexto da instância, eu precisa de algum recurso que me permitisse delegar a criação de alguns campos nesse momento de indexação (instancia). Esse recurso de “dynamic” é exatamente isso: ele  configura um bloco que será criado quando ele for indexar. Com isso eu pude buscar no SOLR por campos que só existem para algumas inscrições.

Em termos de código é mais ou menos o seguinte. Imagine que sua Inscricao tenha uma relação has_many com Resposta.

class Inscricao << ActiveRecord

has_many :repostas

end

A classe Resposta faz referencia a um campo de seu formulário. Logo a busca terá como nome do campo do indice o campo + id e seu valor será a resposta. Assim o mapeamento fica:

searchable do

dynamic :respostas do

respostas.inject({}) do |mapa, resposta|

mapa.merge({ resposta.campo.id.to_sym => resposta.valor})

end

end

end

 

Com isso acima, fica pronto a configuração. Para busca fica assim:

search do

dynamic :respostas do

with(:1, “teste”)

end

Assim estou buscando por Inscrições cujo a resposta a pergunta 1 foi teste. E pronto. A mágica foi feita.

Espero sinceramente que isso ajuda alguém como outros blogs que consultei me ajudaram. Fiquem em paz e até a próximo.

Published by Andre, on abril 8th, 2011 at 8:39 pm. Filled under: atualidades,codigo Tags: , , , 1 Comment

Usando Sinatra para evitar overdesign

Muita gente que  deseja começar um projeto de sistema web e quer ser rápido e produtivo, logo pensa em usar Rails. Rails é um excelente framework, desenvolvido pelo pessoal da 37signals, que é realmente muito produtivo no que diz respeita a entrega de funcionalidade. Porém até o Rails pode ser um overdesign e um má escolha, dependendo do que deseja realizar.

Ruby on Rails, ou RoR ou somente Rails é uma framework de desenvolvimento de aplicações web, cuja a filosofia gira em torno de evitar ao máximo desperdícios com configurações, repetições, etc. Para ser bem objetivo, em Rails tudo é baseado em convenção e tudo é voltado para se escrever o mínimo de código para se implementar um comportamento. Caso queira saber mais peça ajuda ao grande oráculo (google)… para ajudar um pouco você pode começar pelos Railscast que são gratuítos e ajudam muito a entender.

Mas sendo tão orientado a produtividade como o Rail é, ele também pode se tornar um overdesign – um escolha que tem mais recursos e estruturas do que precisa – e uma má escolha para quem deseja fazer um sitema web muito simples e com poucos recursos.

 

Imagine que você deseja fazer um sistema web que simplesmente irá receber uma requisição do usuário, tratá-la (sem necessariamente criar algo num banco de dados, por exemplo) e renderizar uma resposta. Um bom exemplo disso foram alguns projetos que foram feitos durante o evento FISL 2010, pela galera #horaextra.  No meio do evento, decidimos fazer um site onde teríamos ao invés de um horóscopo, teríamos um desoróscopo, com mensagens nada animadoras. Assim surgiu o desoroscopo.

A princípio todo ele foi feito usando Rails. Mas logo nos primeiros releases, fomos vendo que não precisávamos de muitos recursos, principalmente de um banco de dados. Sendo assim, ter ali um activerecord, activecontroller, routes e etc era algo que não precisávamos. Era um overdesign para a solução que desejamos.  Foi então, que o Marcos Tapajós, tomou a iniciativa de reescrever todo o sistema usando outro framework ruby  baseado em RACK que é mega simples : SINATRA.  Vale ressaltar que essa reescrita foi feita em menos de uma hora(a se levar em conta o fato do Tapajós dominar bem ruby e o próprio Sinatra) .

A questão que o site está até hoje no ar e tem números bem expressivos de visitas e em nenhum momento não sentimos falta de algum recurso que rails tem e o Sinatra não.

Sinatra é um framework web feito em Ruby baseado em Rack. Em sua própria documentação, seus criadores, vão além e o chamam de DSL ressaltando sua simplicidade. Todo o seu poder está no fato de precisar de quase nada para estar funcionando. Chega ao limite de precisar apenas a gem instalada e um script com as definições de rotas e seus tratamento in line. Veja exemplo abaixo retirado do site da documentação.

# myapp.rb
require 'sinatra'

get '/' do
  'Hello world!'
end

Note que com apenas 3 linhas de código o sistema ao acessar a url padrão (localhost:4567) já está respondendo. Isso é realmente impressionante.  Entretanto, tudo tem um preço. Caso precise fazer algo que vá além do muito simples, estará por sua própria conta e risco. Claro que pode lançar mão de uma gem para ajudá-lo (isso é algo muito comum no ecossistema Ruby) mas nem tudo será resolvido.

Carrego comigo uma regra que sempre me ajuda muito.  Se meu sistema precisa de mais do que uma entidade, entidades que se relacionam, vai além do que uma 4 ou 5 rotas… já começo a tender para usar o Rails do que qualquer d’outra coisa. Mas se meus sistema não fala com banco de dados, tem poucas rotas, sempre que posso farei com usando Sinatra.

Tenho mais dois exemplos sobre isso:  Sou um dos organizadores do DevinRio, e na edição de 2010, tínhamos os desafio de fazermos um site. Na hora optamos por fazê-lo toda usando Sinatra. Isso porque sinatra é simples e aproveitamos a facilidade de deploy e gestão do produto heroku.  O sistema aguentou requisição para caramba e foi um sucesso, tanto que vamos usar a mesma infra/tecnologia para a edição deste ano.

O segundo exemplo vem do meu trabalho:  precisávamos criar um sistema que iria receber uploads de mídias (fotos, vídeo, etc), gravá-las no disco e processá-las de forma assíncrona.  Muitos poderiam pensar que esses requisitos nos levariam facilmente a querer fazer isso com rails ou até com outra tecnologia/framework(scala, java, etc).  Entretanto, resolvemos fazê-lo em Sinatra. Foi a melhor decisão.  A aplicação ficou simples, limpa e coesa.  E com ajuda de algumas outras gems, o Sinatra está dando conta do recado com maestria.

Enfim, até os mais famosos podem não ser as melhores escolhas. Por isso, fica a dica: fique atento. Leia bastante, converse com outros colegas, amigos e profissionais. Esteja aberto as novidades. Elas podem acabar salvando o seu dia. Evite resolver tudo sempre da mesma forma. Diversifique. Mesmo que seja apenas para testar.  Pluralidade é a palavra da vez.

Published by Andre, on março 20th, 2011 at 10:31 pm. Filled under: agil,atualidades,ruby Tags: , , , , 2 Comments

Colocando auditoria de mudança na sua app Rails

Bom no meu projeto atual estou usando Ruby on Rails. Estou adorando. A coisa é realmente fantástica e me sinto obrigado a dizer que é a melhor opção para desenvolver produtos web.  Mas não é por isso que resolvi escrever este post. Quero compartilhar um aprendizado adquirido.

Dentro da nossa aplicação precisamos mapear (auditoria) as alterações que são feitas em um determinado objeto.  Seria registrar no banco de dados quais campos alterados e, além disso, registra também qual era o valor antes e depois da alteração. Vamos a um exemplo.  Imaginemos que tenho um usuario; esse usuário tem nome, telefone e endereço. Ao alterar o nome dele, quero que fique resgistrado que seu nome foi alterado de um valor “A” para um valor “B”.

Ficando claro a necessidades vamos para a solução.  Passei então para procurar algum plugin que me ajudasse nessa missão. Encontrei vários.  ”Acts_as_audited”,  foi um dos mais interessante que encontrei e recomendo se seu modelo for simples sem relacionamentos muito para muitos.  Mas apesar do plugin resolver o problema, fiquei intrigado de como seria possível fazer isso. Imaginei soluções das mais mirabolantes. Desde de criação de metodos proxies, a magias negras de alta classe (desculpem a brincadeira rubistas) .

Oque achei, como tudo no Ruby, foi a coisa mais simples e fácil já vista. Desde a versão 2.0 do rails, as classes active records ganharam alguns métodos que ajudam bastante nessa missão. São eles: changed?, changes, <atributo>_changed?, <atributo>_was, etc.

changed?  : ele indica se houve ou não alteração nos atributos do objeto. (false se não e true se sim)

changes : devolver um dicionario com as alterações que ocorreram. A chave dele é a propriedade e o valor é uma tupla com o valor antigo e o novo valor

<atributo>_changed? : é um metodo que diz se o atributo mudou. Algo como : usuario.nome_changed?

<atributo>_was : mostra o valor antigo do atributo

<atributo>_will_change! : meio que força a flag indicando que houve uma alteração.

Com esses métodos na mão é possível, sem ajuda do plugin fazer você mesmo sua funcionalidade de auditoria do sistema de forma bastante maneira.  Basta além deles usar os triggers before e after (create, update, etc) do model para chamar os métodos que farão a mágica acontecer.

Espero que ajude. Para saber mais, veja o screencast: tracking_attribute_changes.m4v

Abraços e até a próxima

Published by Andre, on julho 15th, 2010 at 6:51 pm. Filled under: ruby Tags: , , , , , No Comments

Não sejamos tão radicais…

Uma das coisa que me incomodam bastante no meio de informática é que muitos de nós são um tanto radicais. Canso de escutar pessoas dizerem que somente a tecnologia delas  – que elas usam – é a melhor. Em minha humilde opinião, comentários a parte (já escrevi, inclusive, sobre isso), não existe o ideal e a tecnologia mais adequada para o problema.

Como disse antes não quero me ater a discussão do porque não existe uma tecnologia legal e se devemos conhecer mais de uma pois isso, já amplamente abordado inclusive por mim.  Quero apenas rebater um poucos os fanáticos.

Atualmente temos uma clara evolução do uso de duas tecnologias principalmente: Python e Ruby. O Ruby quase exclusivamente impulsionado pelo Rails ( framework de desenvolvimento altamente produtivo de aplicativos web) e python pelo seu poder ( o famoso battery include) e também por alguns de seus frameworks ( Django, Web2Py, Zope, Plone, etc)

Uma coisa que me incomoda um pouco na galera é que por muitas vezes, o pessoal que está chegando agora, vem tomando logo formas de pensar radicais. Um exemplo disso é o discurso mais do que batido que Java é mal.

Gente, sinceramente, Java não é mal. Muito pelo contrário, foi uma grande porta, primeiro passo, para todo esse boom que temos visto. Java, embora não seja  opensource, sempre fomentou o software livre e acabou por criar uma comunidade forte em seu entorno. Essas mesmas comunidades  que são veneradas por  muitos dos que negam o java,  surgiram desse movimento graças ao Java.

O grande problema, da linguagem,  que ela parou no tempo. O que por um bom tempo, sobre somente alguns pontos de vista, ajudou a protegê-la foi o mesmo que a engessou-la. Se ela tivesse se aberto para modificação, mesmo que gradualmente, possivelmente  ainda estaria sendo usada e adorada como antes.

É certo que criar um aplicação em rails é muito mais produtivo do que criá-la em Java ( mesmo com todos os frameworks existentes).  O mesmo vale para o Python em até outros casos.  Então por que estou, aparentemente, defendendo-a? Simples, pois quero mostrar que ainda existe vida após a morte nesse nosso mundo de TI.

Java , para “competir”  com essa galera tem “renascido” com outras formas que permitem sermos mais produtivos.  Um exemplo que gosto muito é o Groovy. O Groovy, senão me engano, foi criado por 2002 ou 2003 como uma linguagem alternativa para rodar dentro da JVM (java virtual machine). Graças ao seu sucesso foi implementada a um especificação para tornar a JVM capaz de entender outras linguagens.

Groovy é um Java melhorada e evoluído para os moldes desses novos paradigmas trazidos por Ruby, Python, etc.  Trouxe uma produtividade maior. Hoje é possível fazer uma aplicação nos moldes de Rails em “Java” /groovy usando o framework Grails.

Outra faceta desse mesmo ponto de vista tem sido o JRuby. JRuby é uma implementação do interpretador do Ruby para a JVM. Assim é possível executar código escrito em Ruby a partir da JVM.

A coisa não para por aí. Basta uma simples busca no google para vermos outros exemplos desse renascimento em outras formas do Java.

E ainda tem a pŕopria linguagem que não para de evoluir e ainda tem o seu espaço. Acredito sinceramente, que existem alguns problemas (requisitos)  os quais a melhor solução seja implementar a solução em Java.

Bom com certeza ainda terão aqueles que dirão que suas linguagens tem as melhores ferramentas. Concordo plenamente. Para mim, falando por exemplo de testes – TDD e BDD,  cucumber, rspec, mocka, should-dsl, lettuce, entre outras são estado da arte. Porém, já encontrei coisas em “Java” (entenda aqui conseguir testar código java, pois tem ferramenta em Groovy por exemplo) que pelo menos chegam perto disso.

Bem a princípio era isso que gostaria de dizer, até a próxima pessoal.

Published by Andre, on junho 16th, 2010 at 9:55 pm. Filled under: codigo,django,Groovy,Java,python,ruby Tags: , , , , , , No Comments