RubyConfBR superando expectativas

RubyConfBR

Mais uma vez participei da RubyConfBR e desta vez tive a oportunidade de apresentar uma palestra. Pra mim foi uma experiência excelente palestrar em um evento desse tamanho, que conta com apenas duas trilhas, o que garante casa cheia.

A apresentação foi sobre “Rails nas nuvens” onde explanei sobre as ferramentas, serviços e práticas para publicar aplicações Rails em uma estrutura de Cloud Computing. Tive um feedback muito bom do público e também gostei do resultado. Pra quem quiser, os slides da minha apresentação estão logo abaixo:

Este ano todas as palestras estavam sendo transmitidas pela internet com público médio de 500 pessoas e você pode assistir a gravação aqui! O evento contou com um público de 700 pessoas e diversos palestrantes de peso no cenário nacional e internacional.

Infelizmente não assisti muitas palestras, mas tive a oportunidade de conhecer várias pessoas interessantes e também rever amigos de outros carnavais. Conheci também um novo local para ficar em SP, o Paulicéia Hostel, que fica logo atrás do Shopping Frei Caneca e com certeza foi um dos melhores hostels em que fiquei.

Vou estender um pouco o assunto da palestra em um artigo que enviei para a Rails Magazine, que será lançada em breve em edição digital e gratuita. Parabém a Locaweb e Fábio Akita por organizarem mais uma vez um grande evento!

Screencast – Buscas e Rails primeira parte

Olá a todos. Já estava na hora de lançar este screencast (a quase um mês venho prometendo).

Efetuar buscas em modelos é algo que com ActiveRecord se tornou super fácil mas relacionar objetos e buscar em vários locais é um problema para quem está começando. Tentarei em três episódios mostrar como fazer buscas em seus conteúdos gravados no banco de dados de maneira simples.

O primeiro episódio será baseado em consultas no banco de dados, o que é uma solução um tanto quanto antiga, mas resolve para pequenas aplicações sem grande complexidade. A idéia em si pode ser utilizada de outras maneiras por isto achei interessante expor a mesma.

Código-fonte com aplicação pronta

Código-fonte com aplicação em fase inicial

Resumo em texto:

Criar model de buscas

rails g model Busca texto:string objeto_id:integer objeto_classe:string
rake db:migrate

Configurar observers

# config/application.rb

config.active_record.observers = :buscas_observer

Callbacks dos observers

# app/observers/buscas_observer.rb

class BuscasObserver < ActiveRecord::Observer
  observe :post, :foto
  def after_create(objeto)
    criar_busca(objeto)
  end

  def after_update(objeto)
    if Busca.where(hash_comum(objeto)).exists?
      busca = Busca.where(hash_comum(objeto)).first
      busca.update_attribute(:texto, unir_texto(objeto))
    else
      criar_busca(objeto)
    end
  end

  def after_destroy(objeto)
    Busca.where(hash_comum(objeto)).delete
  end

  def hash_comum(objeto)
    {:objeto_id => objeto.id, :objeto_classe => objeto.class.to_s}
  end

  def unir_texto(objeto)
    objeto.attributes.find_all{|t,v| v.is_a?(String)}.collect{|t,v| v}.join(' ')
  end

  def criar_busca(objeto)
    Busca.create!(hash_comum(objeto).merge(:texto => unir_texto(objeto)))
  end
end

Gerar novamente o índice para models existentes

Foto.all.each{|t| t.update_attribute(:updated_at, Time.now)}
Post.all.each{|t| t.update_attribute(:updated_at, Time.now)}

Criar o método de cast

# app/models/busca.rb

default_scope :order => "created_at DESC"
def cast
  Kernel.const_get(objeto_classe).find(objeto_id)
end

Ajustar controller de busca

# app/controllers/buscas_controller.rb

def index
  busca = params[:busca].to_s
  @resultados = Busca.where("texto LIKE ?","%#{busca}%")
end

Ajustar index de buscas

# app/views/buscas/index.html.erb

<% @resultados.each do |resultado|%> <% objeto = resultado.cast%>

<%=objeto.titulo%>

<%=truncate objeto.texto, :length => 200%> <%=link_to 'ver', objeto%> <% end %>

Criando sua aplicação Rails + Android

Olá a todos. Que android é o que há no momento todo mundo já sabe. Mas para alguns desenvolvedores que vem de outra linguagem como Ruby pode parecer uma coisa de outro mundo desenvolver em Java. Na verdade isto pra mim ainda é um terreno desconhecido mas vamos lidando.
Meu intuito com este post é mostrar uma aplicação simples, bem simples mesmo, onde um formulário de uma aplicação em android envia informações via Post para uma aplicação rails. Vou tentar ser direto ao ponto e me desculpem pelas asneiras em java, como já escrito acima, não sou o melhor exemplo nesta área. Prontos ou não… da hadouken Ryu…
Vamos fazer a parte simples: a aplicação em Rails 3 que cadastrará as fofocas que pessoas contaram uma das outras

rails new fofoca
cd fofoca
bundle install
rails g scaffold Segredo de:string para:string ex_segredo:text
rake db:migrate
rails s

Acessando localhost:3000/segredos é possível verificar o que as maracutais que serão enviadas como segredos =)
Agora vem a parte do android que por sinal é simples. Estou partindo do princípio que quem está lendo possui Eclipse com Android instalado e configurado. Caso não tenha veja esses links, é rápido e simples.

how to http://developer.android.com/sdk/installing.html

downloads necessários http://developer.android.com/sdk/index.html

Ok então… lá vão os códigos:
Arquivo de layout main.xml (tela inicial da aplicação)








E o arquivo Main.java

package com.toledo;

import java.util.ArrayList;

import java.util.List;

import org.apache.http.HttpResponse;

import org.apache.http.NameValuePair;

import org.apache.http.client.HttpClient;

import org.apache.http.client.entity.UrlEncodedFormEntity;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.impl.client.DefaultHttpClient;

import org.apache.http.message.BasicNameValuePair;

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.TextView;

public class Main extends Activity {
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Button btnEnviar = (Button) findViewById(R.id.btnEnviar);
    btnEnviar.setOnClickListener(new View.OnClickListener() {
      public void onClick(View view) {
        enviarParaCadastro();
        Intent myIntent = new Intent(view.getContext(), TrackMeet.class);
        startActivityForResult(myIntent, 0);
      }
    });
  }
  public void enviarParaCadastro() {
    final EditText editDe = (EditText) findViewById(R.id.editDe);
    String de = editDe.getText().toString();
    final EditText editPara = (EditText) findViewById(R.id.editPara);
    String para = editPara.getText().toString();
    final EditText editExSegredo = (EditText) findViewById(R.id.editExSegredo);
    String ex_segredo = editExSegredo.getText().toString();
    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost("http://10.0.2.2:3000/segredos");
    List pairs = new ArrayList();
    pairs.add(new BasicNameValuePair("segredo[de]",         de));
    pairs.add(new BasicNameValuePair("segredo[para]",       para));
    pairs.add(new BasicNameValuePair("segredo[ex_segredo]",     ex_segredo));
    try {
      post.setEntity(new UrlEncodedFormEntity(pairs));
      HttpResponse response = client.execute(post);
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

Bate-bola sobre os arquivos:
main.xml contém é a tela inicial do projeto com o formulário
Main.java Classe que faz todo o trabalho de criar o evento de clicar no botão Enviar e os dados serem enviados ao servidor. Uma dica importante é que o servidor no caso responde por 10.0.2.2 mas quando for publicar online troquem o endereço certo?!

Pronto… é só fazer o build da aplicação no emulador do android e testar.

Atualizando rubygems e trabalhando com versões anteriores do rails

Muitos de vocês estão na vibe de rails 3.x e querem sempre usá-lo. Mas sabemos que o mundo é feio e ingrato então logo logo você terá que dar manutenção naquele sistema com rails 2.3.5 e dai vai.
O problema é que se você estiver usando RVM e quiser atualizar seu rubygems para 1.5 ou mais e usar rails 2.3.5 verá a seguinte mensagem:

requirement':NameError: undefined local variable or method 'version_requirements' for

Dai em diante é variável mas isso pode ocorrer. O que acontece é que o o rubygems em sua atualização mudou algumas coisas. Para funcionar abra seu environment e abaixo da linha

require File.join(File.dirname(__FILE__), 'boot')

Coloque

if Gem::VERSION >= "1.3.6" 
  module Rails
    class GemDependency
      def requirement
        r = super
        (r == Gem::Requirement.default) ? nil : r
      end
    end
  end
end

Pronto está funcionando =)

RubyMasters 2011 vai bombar

Banner RubyMastersConf

E ai meus queridos (hummmm).
Pra quem está procurando novidades, propostas interessantes para aprendizado e explorar um pouco mais de Ruby, chegou a hora de participar de um mega evento.

Se trata do rubymastersconf. De acordo com a própria definição:

Ruby Masters Conf é uma maratona de palestras on-line que será realizado nos dias 25 e 26 de fevereiro de 2011 que contará com grandes nomes da comunidade Ruby e Rails internacional e Brasileira. O evento tem por objetivo compartilhar o conhecimento e ainda arrecadar fundos para projetos opensource.

Preciso informar algo mais? Vamos participar e penso ainda em submeter uma palestrinha.