BD em Ruby
2011-01-19 01:31:08
2011-01-18 23:40:06
Autor: Sony Santos
http://gigawiki.com/sony/bd-em-ruby
Permalink: http://gigawiki.com/928
área = informática; assunto = Banco de Dados; categ = dicas, list; linguagem = ruby, sql
Mal comecei a aprender Ruby e, já nos primeiros testes, estou precisando acessar banco de dados. Imaginava que, como existem as classes Array, String, Hash, Integer, etc., também haveria uma DB e seria só aprendê-la a usar. Mas, como em outras linguagens, acessar BD não é uma coisa única (isto é, um jeito único já provido como recurso nativo da linguagem).

Nesta página aprendi que há 3 formas populares de usar BD em Ruby:

1. Pelo driver do banco de dados. Isso varia muito com o driver. Exemplo:
results = mysql.query("SELECT * from rocks;")  # mysql
results = conn.exec('select * from rocks')     # postgree
results.each do |row|
  ...
end
Isso inviabiza mudanças de base de dados no futuro, pois exige alterar todo o código.

2. Pela interface DBI, que é uma interface única para diferentes bancos de dados:
query = dbh.prepare("SELECT * FROM rocks")     # o mesmo código para diferentes bancos
query.execute()
while row = query.fetch() do
  ...
end

Para quem vem do PHP, como eu, a primeira interface lembra o MySQLi, pela semelhança, e a segunda lembra o PDO, pela filosofia de prover uma interface independente do BD.

Na época da decisão entre o MySQLi e o PDO, optei pelo primeiro, porque não pretendia mudar de BD e porque soube que o PDO não teria como aproveitar todos os recursos do MySQL, justamente por seu desapego a algum BD em particular.

No entanto, o MySQLi, mesmo tendo uma interface orientada a objetos, não me satisfazia, pois parecia uma linguagem procedural disfarçada de OO. Então criei algumas classes para realizar queries e trabalhar com resultados à maneira OO, com method chaining, heranças e tudo o que a orientação a objetos oferece de útil e produtivo.

No exemplo acima, seria assim:
$results = $my->new_query()->from_tabela('rocks')->lc()   # retorna uma matriz linhas x colunas
foreach($results as $row) {
  ...
}

Mas é muito mais que isso. Sempre achei que os registros deveriam ser objetos, com métodos como insertupdate, etc. O jeito mais apropriado de usá-las seria, por exemplo:
$query = $my->new_query()->from_tabela('rocks')->add_cond('name like ?', 'a%');
while ($row = $query->fetch()) {
  $id = $row->valor('id');
  $name = $row->valor('name');
  ...
}

# alterando um campo
$row->set('name', 'Turquesa')->update();

# inserindo um campo
my_registro::_new($my, 'rocks')->set('name', 'Ametista')->insert();

Implementei todas essas coisas.

Bom, eu havia mencionado que aprendi 3 formas de usar BD em Ruby, mas só falei de duas.

3. A terceira é o ActiveRecord, muito usada pelo framework Ruby on Rails.

Quando vi os códigos de exemplo me apaixonei. Me identifiquei imediatamente. É a versão pronta para Ruby do que eu havia construído manualmente para PHP.

Nele, as tabelas são classes e as linhas são suas instâncias. É assim que as coisas têm que ser!
queryresults = Rock.find(:all)
queryresults.each do |row|
  print row.id, "   ", row.name, "\n"
end

# inserindo nova rocha:
newrow = Rock.new
newrow.name = "Basalto"
newrow.save

Ok, vamos aprender ActiveRecord!

Pesquisando no Google, abri algumas páginas e uma delas era sobre um tal de Sequel, que se dizia um toolkit para BD em Ruby. "Um concorrente do ActiveRecord", pensei. Ora, se o AR é tão usado no Rails, por que perder tempo aprendendo outra coisa? Mas o curioso aqui foi fuçar e descobriu uma comparação em que o Sequel se mostra muito superior! (veja sobre as diferenças).

Vejamos aquele mesmo exemplo:
# select * from rocks
DB[:rocks].each do |row|
   ...
end

# com uma condição
DB[:rocks].filter{:id => [10, 15, 17]}.each do |row|
   ...
end

# inserindo uma rocha
DB[:rocks].insert(:name => 'Quartzo')

Conclusão: mal comecei a aprender o ActiveRecord, que me parecia o melhor dos melhores, e encontro algo melhor ainda! (De fato, eu gostei tanto que nem terminei de ler aquela comparação: eu precisava redigir este post!)

Muito legal a comunidade do Ruby oferecer recursos como esses! É um grande atrativo para novos usuários. 
blog comments powered by Disqus
Login:
Senha:
Para logar, você precisa ter o Javascript habilitado.