Seguindo a seqüencia que eu iniciei aqui, mas alterando a ordem proposta, Vamos conversar um pouco sobre os Geradores de código do Rails.
Generators são uma das coisas mais legais do Rails!
Sim, você ja viu eles, lembra do primeiro screencast sobre rails que você viu? Sim, aquele mesmo em que um cara cria um CRUD em 1 minuto …
Generators são a “forma rails” de gerar código
Mas o código gerado não precisa ser apenas aquele CRUD, ele pode ser o que você quiser, e o Rails ja tem um suporte excelente para isto, pois este mesmo suporte ja é utilizado na base do Rails.
Beleza, mas por que eu iria querer escrever um gerador de código?
Pense sobre o projeto que você estaria começando hoje, lembre de todos aqueles formulários para CRUD que você precisara criar, ou aquela parte quase igual de todas as páginas da aplicação …
Agora pense em todas as aplicações da empresa que você trabalho …
Entendeu agora?
Sim, eu concordo que utilizar o “scaffold” padrão não é realmente útil, mas se esta geração de código inicial for feita seguindo os padrões da sua empresa, ela pode aumentar muito a velocidade de desenvolvimento inicial das aplicações …
Agora eu imagino que você esteja pensando: Legal, generators são show de bola, mas para de falar besteira e me mostre o código!
Então, vamos brincar um pouco …
Vamos iniciar criando um novo projeto rails: rails plugins102
agora de dentro do diretório do projeto execute: script\generate plugin my_generator
(Se você esta pensando que você ja viu isto antes, provavelmente você leu o post anterior sobre escrita de plugins para o rails
)
Agora que você a criou a estrutura para um novo plugin, vamos escrever algum código!
Para criar um novo generator, você precisa criar um diretório de nome “generators” dentro do diretório do plugin, um diretório com o nome do seu generator dentro deste, e um diretório de nome “templates” dentro do diretório do seu generator, por exemplo a minha estrutura ficou assim:
Na verdade, você não precisa de um plugin para criar um generator, você pode colocar o seu novo generator dentro de qualquer um dos seguintes diretórios:
Mas eu acho que um plugin é a orma mais fácil de começar, e vai ser mais fácil de utilizar nas suas aplicações também, mas claro que se você for utilizar isto em diversas aplicações um GEM seria melhor pois você teria apenas uma cópia do código para todo o servidor, mas como eu nunca criei um GEM vou continuar com o plugin pelo menos para este exemplo …
para o código do generator nos vamos criar um arquivo no diretório do generator de nome [nome_do_generator]_generator.rb, no meu caso o nome do arquivo ficou: my_generator/generators/test_gen/test_gen_generator.rb
Agora dentro deste arquivo precisamos criar a classe que define o generator, esta classe deve ter o nome de acordo com o nome do arquivo (seguindo os padrões do ruby), no meu caso o nome da classe precisa ser TestGenGenerator, e ela precisa extender uma das classes padrão para generators do rails (na verdade eu poderia não extender nada e implementar um monte de métodos, mas assim é bem mais fácil
), estas classes são:
Rails::Generator::Base ou Rails::Generator::NamedBase, eu vou utilizar NamedBase (A base para o controller generator do Rails), e vou criar um modelo de generator para uma migration apenas para mostrar como isto funciona …
NamedBase é uma ótima base para geradores que esperam parametros no formato: Nome [parametro1] [parametro2] …
Para todos os outros Base é uma melhor pedida …
O nosso código inicial é este:
1 2 3 4 5 6 7 | class TestGenGenerator < Rails::Generator::NamedBase def manifest record do |m| end end end |
Nesta classe precisamos configurar o manifesto do generator e configurar quaisquer variáveis locais que utilizemos nos templates.
Mas com o código que nos temos, você ja pode executar: ruby script\generate test_gen asdas_dasda asd:ash (letras aleatórias como parâmetros por hora).
NamedBase ja vai configurar algumas variáveis para nós quando executarmos este comando:
Claro que por enquanto não estamos gerando absolutamente nada, por que o manifesto do gerador esta em branco, então vamos criar um exemplo simples para ver como isto realmente funciona …
Vamos criar um diretório de nome “dummy” dentro do diretório “template” e um arquivo em branco de nome “log.log” dentro deste, e vamos fazer as seguintes alterações no manifesto:
1 2 3 4 5 | def manifest record do |m| m.file 'dummy/log.log', "log/#{file_path}.log" end end |
Este código vai dizer para o gerador copiar o nosso arquivo em branco para $APP_ROOT/log/asdas_dasda.log se executarmos o gerador com os mesmos parâmetros que antes …
Mas apenas copiar arquivos de um lugar para outro não é uma coisa muito divertida, então vamos brincar um pouco com o ERB, e vamos criar uma migration para o nosso plugin, para isto vamos alterar novamente o manifesto como no seguinte exemplo:
1 2 3 4 5 6 7 8 | def manifest @migration_name = "Create#{class_name}" @migration_action = "add" record do |m| m.file 'dummy/log.log', "log/#{file_path}.log" m.migration_template 'lib/mymigration.rb',"db/migrate", :migration_file_name => "create_#{file_path}" end end |
Como você pode ver no código, estou informando ao gerador que eu tenho um arquivo de nome mymigration.rb dentro do diretório templates/lib, este template vai ser processado pelo ERB e o código gerado vai ser colocado no diretório “db/migrate”e vai ser chamado XXX_create_asdas_dasda.rb (XXX vai ser o número da migration gerado automaticamente pelo rails)
O conteúdo do arquivo mymigration.rb é o seguinte:
1 2 3 4 5 6 7 8 9 10 11 | class <%= migration_name.underscore.camelize %> < ActiveRecord::Migration def self.up<% attributes.each do |attribute| %> <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><% end -%> <%- end %> end def self.down<% attributes.reverse.each do |attribute| %> <%= migration_action == 'add' ? 'remove' : 'add' %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'remove' %>, :<%= attribute.type %><% end -%> <%- end %> end end |
este é um template ERB que vai gerar código ruby.
Agora que ja temos um plugin razoavelmente útil , vamos ver o que mais é possível fazer …
para responder esta pergunta, vou copiar parte da documentação da classe Rails::Generator::Commands::Create, ou seja, todas as possibilidades de comandos para o manifesto do gerador:
Acho que era isto, você pode fazer perguntas nos comentários se quiser, vou tentar responder todas (se é que alguem vai perguntar
)
Para mais documentação sobre generators do rails siga os seguintes links:
http://wiki.rubyonrails.org/rails/pages/UnderstandingGenerators
http://www.aidanf.net/node/33
http://api.rubyonrails.org/classes/Rails/Generator/Base.html
http://api.rubyonrails.org/classes/Rails/Generator/NamedBase.html
http://api.rubyonrails.org/classes/Rails/Generator/Commands/Create.html
Espero que este passo a passo ajude alguem!
O próximo vai ser sobre testar o seu plugin! e o quarto eu ainda não pensei sobre o que vai ser, sugestões são bem vindas
Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!
Tags: generator, howto, passo a passo, plugin, rails, Ruby, step by step
Ola urubatan bl??
Reply to this commentBem muito bom a ideia deste artigo e o o ruby pelo geito ta se mostrando muito pratico.
Voce acha que o ruby on rails é realmente melhor que jsp e compania ??
Tenho vontade de aprender essa nova linguagem mais.. ainda nao existem ferramentas eficientes , diferente do java …..
Quando tiver um bom compilador e tal…eu vo com tudo. !!!!
seguinte, a falta de ferramentas assunta quem vem do java no inicio (como eu),
mas com um pouquinho de prática tu vai ver que estas ferramentas mais atrapalham do que ajudam no caso do ruby
o melhor editor para rails que achei até o momento é o VIM
)
Reply to this commentoutra ótima pedida é o Komodo Edit que é gratis (o Komodo IDE tem muito mais recursos mas é pago
legal cara.. obrigado pela resposta.
Reply to this commentMas diga ai.. essas ferramentas compila e roda mostra erro e etc???
valew!
é uma linguagem interpretada e não compilada, mas isto não faz falta, no final das contas é até vantagem …
Reply to this commentse não fosse isto não seria possível ter coisas como Open Classes e Mixins
humm…
Reply to this commentcool
Ultima pergunta…srsr (prometo)
tipo isso ai que vc fez eu posso fazer com o JRuby? no netbeans,,
sim, isto é recurso do rails, rails roda sobre o jruby também, por tanto, pode fazer com o jruby sim.
Reply to this comment[...] Escrevendo plugins para o Rails - dicas e truques - plugins com generators [...]
Reply to this commentMuito bom o Tutorial está ajudando muito!
Reply to this commentPS: vou linkar seu tuto em meu blog
Reply to this commentparabens d novu
^^
[...] Escrevendo plugins para o Rails - dicas e truques - plugins com generators [...]
Reply to this commentE se eu quiser criar algo como:
> script/generate meu_plugin
#=> para acrescentar um código especifico no application.js, por exemplo?\.
E ainda criar també algo como:
> script/destroy meu_plugin
#=> para remover o mesmo código inicialmente gerado através de regexp
Tem como?
Reply to this comment