Onde posso usar Singleton Classes ?

Posted on November 4, 2009

2


Há um tempo escrevi sobre Ruby Singleton Classes, já nesse post vou criar um plugin bem simples que facilita buscas no Rails e ver uma forma onde singleton classes podem ser úteis.

Atualmente pra fazer uma busca ordenada precisamos fazer algo como:

Picture 1
A partir do momento que instalarmos nosso plugin na aplicação poderemos fazer a busca dessa forma:

Picture 2

Nosso plugin não é nenhum idéia inovadora, mas sim uma necessidade ou problema onde precisaremos utilizar Singleton Classes. Vamos criar uma aplicação de exemplo para criar, instalar e usar o plugin:
Picture 11
Não vou colocar aqui toda a sequência para gerar a aplicação base, mas esse roteiro acima deve ajudar.

Agora vamos comecar a gerar nosso plugin, vamos chamá-lo de default_options.Para iniciar basta rodar => ruby script/generate plugin default_options

Rails plugins e Singleton classes

Agora é preciso adicionar um novo comportamento ao ActiveRecord, a necessidade do plugin é adicionar um método novo a base do ActiveRecord que mude seu comportamento padrão, para isso vamos utilizar Ruby Singleton Classes:

Picture 4
Esse codigo abre a classe Base do módulo ActiveRecord e podemos adicionar qualquer novo comportamento nele.

O objetivo agora é definir um comportamento default quando o método default_find_option for chamado.

Picture 5
Mas isso ainda não muda o comportamento do find, precisamos mesclar o find normal com os parametros passando pro nosso default_find_option. Pra isso vamos redefinir o find:

Picture 6
Quase bom, mas a chamada do find na última linha faz nosso código entrar em um loop infinito, vamos resolver isso da seguinte forma:

Picture 7

Agora podemos chamar nosso método adicionado ao ActiveRecord via plugin. Como teste podemos gerar alguns carrors com fixtures
(test/fixtures/carros.yml):

Picture 8
E rodar alguns testes pro nosso plugin (test/unit/carro_test.rb):

Picture 9

Não vou cobrir aqui como distribuir o plugin, isso fica pra um próximo post.
github => default_find_options

Posted in: rails, ruby