Arquivos de Rails
03/11/2008 às 01:53 · Postado em Rails
Bom, todo mundo fica dizendo que os plugins são a melhor parte de rails, que a comunidade participa muito, bla bla bla. Decidi então mostrar como fazer um plugin. Aliás, decidi aprender. Não tem muito material sobre isso, principalmente em português. Esse post foi escrito depois de ter lido:
Como é um assunto meio grande, decidi dividir em algumas partes. Nessa primeira, vou mostrar como estender uma classe de Ruby, criar um generator pra gerar migrations e adicionar um acts_as nos models, para adicionar métodos e outras coisas. Como exemplo, vou criar um plugin que adicionará algumas funcionalidades simples de loja à aplicação, chamado little_store. Para isso, ele precisa de um resource Product. Não vou utilizar testes, para que o post não fique muito grande. Talvez eu fale sobre testar plugins em outra oportunidade. É importante notar que algumas coisas que vou mostrar não são as melhores formas de se fazer, como estender BigDecimal pra criar um método que gere uma saída formatada em Real. Já existem helpers prontos que fazem isso. Os exemplos são só pra ilustrar o que estou dizendo, esse plugin não é útil :)
Iniciando
A primeira coisa a se fazer é gerar a aplicação, e verificar se está tudo certo:
rails littlestore
cd littlestore
script/generate scaffold product name:string, description:text
rake db:migrate
script/server
Depois, é preciso gerar o plugin:
script/generate plugin littlestore --with-generator
Essa opção, --with-generator, irá criar um modelo para os seus generators. Se seu plugin não for ter um generator, ela é desnecessária. Essa é a estrutura gerada:
littlestore
|-- generators/
|-- littlestore
|-- littlestore_generator.rb
|-- templates/
|-- USAGE
|-- init.rb
|-- install.rb
|-- lib/
| |-- littlestore.rb
|-- MIT-LICENSE
|-- Rakefile
|-- README
|-- tasks/
| |-- littlestore_tasks.rake
|-- test
| |-- littlestore_test.rb
|-- uninstall.rb
- init.rb Esse arquivo é carregado toda vez que a aplicação inicia. Você precisa fazer alguns require aqui :) . Bom notar que nem sempre ele é utilizado. O plugin do RSpec, por exemplo, não o usa, pois não faz sentido o plugin ser carregado antes de você ter usado o generator.
- install.rb Carregado somente no momento da instalação.
- lib Nesse diretório fica o código base do plugin. Esse é o padrão, podem ser criadas outras pastas. É sempre bom dividir em alguns arquivos. Ou até pastas, a depender do tamanho do plugin.
- MIT-LICENSE Ele gera um modelo de licensa pra você. Obviamente, você não precisa usá-la, pode fazer o que quiser! Ao contrário da GPL :(
- tasks As rake tasks ficam nesse diretório.
- test Os testes ficam nesse diretório. Se quiser usar RSpec, tem o rspec-plugin-generator
Estendendo uma classe
É fácil estender uma classe em Ruby. Criarei um método em BigDecimal, que é a classe correspondente no rails pra o :decimal das migrations. O método vai apenas formatar o valor pra que ele saia com duas casas decimais e um R$ na frente. Pra isso, criamos um arquivo no diretório lib.
vendor/plugins/littlestore/lib/core_extensions.rb
BigDecimal.class_eval do
def to_real
"R$ #{self.to_f.round(2)}".gsub(".", ",")
end
end
É recomendável usar class_eval ao invés de redefinir com class diretamente. Também é preciso adicionar o arquivo no init.rb
vendor/plugins/littlestore/init.rb
require 'core_extensions'
Pode-se testar com o console do Rails:
script/console
>> d = BigDecimal.new(73.3492.to_s)
=> #
>> d.to_real
=> "R$ 73,35"
Generator que gera migrations
Novamente, o diretório dos generators:
|-- generators/
|-- littlestore
|-- littlestore_generator.rb
|-- templates/
|-- USAGE
O diretório templates/ contém templates feitos pelo usuário, que podem ser utilizados pra criar generators. E o arquivo USAGE serve pra definir o que irá aparecer quando o usuário chamar o generator sem parâmetros, ou seja, como utilizar o plugin, como o nome já diz :)
Quero criar um generator que será chamado por script/generate littlestore Product, onde Product é o model que sofrerá as mudanças (na verdade a tabela desse model que será modificada, certo?). Para isso eu edito o arquivo que foi gerado pelo generator que criou o plugin:
vendor/plugins/littlestore/generators/littlestore_generator.rb
class LittlestoreGenerator < Rails::Generator::NamedBase
def manifest
record do |m|
m.migration_template "migration:migration.rb", "db/migrate", {:assigns => littlestore_assigns,
:migration_file_name => "add_littlestore_fields_to_#{custom_file_name}"}
end
end
private
def custom_file_name
custom_name = class_name.underscore.downcase
custom_name = custom_name.pluralize if ActiveRecord::Base.pluralize_table_names
end
def littlestore_assigns
returning(assigns = {}) do
assigns[:migration_action] = "add"
assigns[:class_name] = "add_littlestore_fields_to_#{custom_file_name}"
assigns[:table_name] = custom_file_name
assigns[:attributes] = [Rails::Generator::GeneratedAttribute.new("price", "decimal")]
assigns[:attributes] << Rails::Generator::GeneratedAttribute.new("quantity", "integer")
end
end
end
Todo generator precisa precisa de um Manifest. E o método record é usado pra criar esse Manifest. Geralmente se cria usando templates. Nesse caso, utilizei o migration_template, já que quero que ele gere uma migration. É bom testar se o pluralize está ativo, para não haver erros com nomes de tabelas. Note também que utilizo um método pra definir o hash assigns, apenas pra ficar mais organizado.
Como dá pra ver, essa migration irá adicionar as colunas price e quantity na tabela do model que foi dado como parâmetro. No meu caso, criei com Product:
script/generate littlestore Product
Esses campos adicionais irão servir pra que o acts_as_buyable funcione.
Criando um acts_as
vendor/plugins/littlestore/lib/acts_as_buyable.rb
module LittleStore
module ClassMethods
def acts_as_buyable
send :include, InstanceMethods
end
end
module InstanceMethods
def buy(qt)
return "We don't have enough items to fullfill your order" if qt > self.quantity
self.quantity -= qt
end
end
def self.included(receiver)
receiver.send :extend, ClassMethods
end
end
Simples, não? self.included é chamado quando o módulo LittleStore é incluído, e o parâmetro é a classe ou módulo que incluiu o LittleStore. Então, receiver irá herdar o módulo ClassMethods, e o método acts_as_buyable estará disponível :) .
Tendo em mente que ClassMethods são os métodos de classe (duh!), como Product.currency, e InstanceMethod os das instâncias, como @product.price, é possível implementar várias coisas aqui. Dá também pra definir atributos, usando cattr_accessor e write_attribute.
É preciso adicionar o arquivo ao init.rb:
vendor/plugins/littlestore/init.rb
require 'acts\_as_buyable'
ActiveRecord::Base.send :include, LittleStore
Essa linha do ActiveRecord não é necessária, mas pra cada model onde o acts_as_buyable será utilizado funcione, é preciso incluir o módulo com include LittleStore.
Na próxima parte mostrarei como fazer routes e helpers customizadas nos plugins. Além de como gerar um RDoc e alguns outros assuntos :)
Comentários (4)
23/10/2008 às 09:51 · Postado em Rails
Bom, eu decidi votar no Rails Rumble. Então, comecei a olhar algumas aplicações. Acho que nesse link tem todas ou a grande maioria. Não usei nenhuma, só dei uma olhada pra ver qual era a idéia. Mais tarde, quando abrir a votação, eu uso pra ver como são realmente. Essas foram as que eu mais gostei:
Eles dizem que é mais simples que um blog, mas não tem o limite de caracteres do twitter. Você pode postar textos, imagens, vídeos, código, etc. Enfim, eles "tiraram a gordura do blog". Eles dizem de uma maneira que parece que foram eles que inventaram a idéia. Não seria um tumblelog? De qualquer forma, a aplicação parece bem feita.
Essa é pra fazer conferências. Eles montam um site pra sua conferência, deixa os (futuros) participantes votarem em quem gostariam de ver como palestrantes, gerenciam inscrições, etc. Apesar de ter outros sites parecidos, esse parece ser bem feito, e bem focado na comunidade que um evento cria, como foi no Rails Summit.
Uma aplicação pra fazer apresentações. Mas aqui eles focaram na simplicidade: Você escolhe um tema (muito simples, apenas cores diferentes), e depois tem formulários pra fazer os slides, que podem conter textos, imagens ou tópicos. Depois de tudo pronto, é só apresentar. Achei bem legal, pra quem quer fazer algo rápido e simples.
Apesar de ter sites similares (e até mais elaborados) como Twellow e Just Tweet It, nenhum deles fez sucesso ainda. O FlockUp pode ter mais sucesso, talvez por inventar esse conceito de "Flocks". Um Flock é um assunto, um grupo, algo em que usuários podem se identificar. E Flockers são usuários de twitter dentro de um Flock. Coloquei meu nick lá no Flock de rails :)
É um diretório de filmes independentes, e dos festivais que passam esses filmes. É uma idéia interessante, não conheço nada parecido. A aplicação é bem feita e tem um bom layout. Talvez eles devessem focar um pouco mais na comunidade, na interação entre os usuários.
Esse aqui tem uma idéia simples e não muito original: Coloque algo que você não pode esquecer, e ele enviará uma notificação. Mas eles exploram mais o conceito, você pode receber essa notificação por email, Twitter, Jabber ou até telefone.
Falando em notificação, o Notifly permite que você integre um sistema de notificação em sua aplicação, sistema esse que deixa o usuário escolher como será notificado. Eles já têm suporte pra email, IMs, Campfire, SMS e Twitter. Mas já planejam aumentar, com Fax(!), MySpace, Facebook, Basecamp, RSS, e outros. A idéia é ótima, mas só testando pra ver como funciona de verdade.
Uma idéia inusitada! Deixe os usuários escolherem quem é a pessoa mais perigosa de cada país (por exemplo, nos EUA tem Bill Gates entre os primeiros). Apesar de estranha, a idéia foi muito bem implementada, um layout bem feito e com direito até a dados demográficos.
Pelo que eu entendi, você manda várias vezes a altura e o peso de seu bebê (mas só quando mudar, não é pra mandar igual :P) pra um bot do Twitter. Depois você vê no site alguns relatórios sobre o andamento do bebê. Gostei porque a idéia é totalmente estranha!
Antes de mais nada, foi a 37signals que fez isso? Bom, TrackClass é uma aplicação feita para os estudantes, para que eles possam gerenciar seus estudos. Eles podem escrever notas sobre cada aula, agendar compromissos [de estudo] e provas, cadastras notas e fazer upload de arquivos. Bem completa, se foi bem feita pode ser bastante útil. Tudo parece com Basecamp, até o tour.
Essa foi feita por uma equipe da giraffesoft, empresa de James Gollick, que fez o resource_controller. Parece bem promissora, você digita o erro de sua aplicação e ele mostra soluções postadas pela comunidade. Além disso, eles fizeram plugins pra Rails e Merb que sobrescrevem as mensagens de erro, em modo de desenvolvimento. Quando aparece um erro, aparece também um link pra página do erro correspondente no site deles.
Que tal fazer pasties e enviar pelo Twitter? É o que o Twippet tenta oferecer. É uma aplicação de pastie normal, onde você tem a opção de mandar o link pelo Twitter. Um TwitPic pra código. Eu não achei muito interessante, mas como o pessoal adora Twitter, talvez dê certo.
Comentários (4)
17/10/2008 às 19:11 · Postado em Eventos, Rails
No segundo dia, eu já cheguei na hora da palestra da Phusion. Muito legal a palestra, brincaram bastante com Star Wars, Scarlett Johansson e Megaman. O conteúdo da palestra foi muito interessante, ensinaram alguns conceitos de deployment, e como fazer sua aplicação escalar. Eu já sabia algo nesse sentido, na camada dos web servers, mas nada na camada do banco de dados, nem na parte de caching, então foi muito instrutiva. Depois eles falaram brevemente sobre uma aplicação que eles fizeram, chamada Yuumi. Tem uma integração com Twitter, SMS, um sistema de votação parecida com Digg. Eles também embutiram comentários num blog, com o plugin yuumius_comments.
Logo após, teve um Coffee Break e a palestra de Charles Nutter e Thomas Enebo, que eu não assisti. Fiquei uma hora no sofá, esperando a palestra de Jay Fields, sobre imaturidade dos testes. Basicamente, ele falou mal de todos os frameworks que existem pra fazer testes. Não disse que você não deve usar nenhum, mas que, obviamente, todos eles possuem desvantagens e você deve estar atento a isso. É que as pessoas estão muito empolgadas com testes, e achando que são perfeitos e não falham. Foi engraçado ver ele falando mal do RSpec com David Chelimsky assistindo.
Depois fui assitir a palestra de Manoel Lemos, que também teve a participação de Ronaldo Ferraz e Nando Vieira. Eles falaram sobre a história da WebCo e como ela está atualmente. Lemos contou a história do BlogBlogs e os problemas que teve por falta de conhecimento em deploy de rails. Mostrou como superou esses problemas e fez a empresa crescer. Ronaldo falou sobre search engines, e como eles criaram uma abstração para que possam utilizar qualquer solução, por meio de drivers. E Nando contou como eles aplicam Scrum na empresa. Gostei do que ouvi, e pude conhecer mais como a WebCo trabalha. Até então era só uma empresa com um monte de gente boa em Rails, e que diziam ser maravilhosa. Acho que agora também posso dizer que parece ser mesmo bom trabalhar lá :)
Fiquei na mesma sala, pra assistir Vinícius Teles. Também foi uma grande palestra, sobre empreendedorismo. Ele contou um pouco da experiência dele com a ImproveIt, e como foi a decisão de mudar de uma empresa que oferece serviços pra uma que oferece produtos. Ele mostrou como você pode ter sucesso fazendo produtos pra pequenos nichos, com uma empresa pequena. Disse também que não é tão difícil fazer algo mesmo não estando em grandes centros como São Paulo e Rio, e deu justificativas.
Depois disso eu fiquei no saguão, ajeitando algumas coisas do blog. Teve um momento em que várias pessoas se juntaram pra gravar um videocast pro RailsBox Podcast. Fechei meu MacBook e fui pra lá. Depois de meia hora "gravando", descobriu-se que na verdade Davis só tinha gravado os 3 primeiros minutos, que foi o pessoal se apresentando. Pelo menos, Ozéias tinha gravado o áudio.
Após esse acontecimento estranho (pra não dizer outra coisa), fomos todos pra palestra de Obie Fernandez. Foi sensacional. Todos adoraram a palestra, que foi até longa. Obviamente, ele falou sobre como a Hashrocket funciona, e porque ele não tem nenhum cliente egípcio. É uma empresa que, pelo menos até agora, vem dado certo e que é bem diferente de empresas tradicionais. E de muitas outras empresas que utilizam Rails e Metodologias Ágeis. Falou sobre pair programming, Scrum, Rails Rumble e do dia-a-dia da empresa.
Depois da última palestra, teve o encerramento do evento, com um coquetel. Ficou muita gente lá, conversando e se divertindo. No final, achei que Obie fez a melhor palestra. Mas tenho também que falar do talento (em apresentar alguma coisa) de Dr Nic, Chad Fowler e os caras da Phusion. O evento foi ótimo, as palestras foram legais e surgiu até um projeto lá, onde várias pessoas colaboraram. Mas o melhor do evento foi (e acho que todo mundo vai dizer isso) conhecer as pessoas. Tanto as que eu já conhecia pela internet, quanto as que eu não conhecia realmente. Pessoas como Ozéias Santana, Davis Cabral e Charleno Pires, que é muito engraçado. Além, é claro, de todo o pessoal da aprendendo-rails: Elomar, William, Juarez, Raúl e o outro William. Até apareceram outras pessoas que estão na lista, mas eu não falava muito, como Marcos e Ricardo.
Segundo Gilberto Mautner e Akita, terá um Rails Summit em 2009. Se tiver, estarei lá com certeza. Até lá, espero ir em algum outro evento local sobre Rails. Ou até, quem sabe, criar um aqui em Salvador. Valeu muito a pena todo o dinheiro gasto, e todas as horas extras que terei que fazer no trabalho pra repor o que eu faltei :)
Comentários (3)
17/10/2008 às 17:21 · Postado em Eventos, Rails
Logo quando cheguei no evento fiz o credenciamento e encontrei Elomar e William, da aprendendo-rails. Ficamos conversando, e depois fomos assistir a palestra de abertura, com Gilberto Mautner, fundador da Locaweb, e Akita. A parte de Mautner foi melhor do que eu esperava, ele contou como começou a empresa e as aventuras dele com ASP, e como a Locaweb está incentivando todos seus desenvolvedores a aprender Rails. Akita falou de como foi seu começo na comunidade Rails e sua vontade de fazer um evento como esse, que se concretizou depois que ele foi pra Locaweb.
Depois da abertura teve o primeiro Coffee Break, onde encontrei o restante dos membros da aprendendo-rails que estavam no evento. De lá, fui pra palestra de Chad Fowler. Tomei um susto com a aparência dele (se não me dissessem que era ele, nunca saberia), mais magro e com menos barba e cabelo. David Heinemeier Hansson teve algum problema e teve que apresentar antes, então colocaram a palestra de Chad no lugar da dele. Ele falou muita coisa que já tinha falado antes, talvez as perguntas não tenham ajudado. Ele disse que o Rails será thread-safe por causa de pressões externas (como JRuby), já que pra MRI não tem muita diferença. Esquivou-se da pergunta sobre a data de lançamento do Rails 2.2, e disse que o Core Team não liga pra ActiveRecord com conexões com bancos diferentes.
Logo depois aconteceu a palestra de Chad, que foi muito boa. A palestra girou em cima da perspectiva de que cada desenvolvedor é um produto. E, como um produto, o desenvolvedor tem que criar sua marca e se promover. E a melhor maneira de fazer isso é "sendo memorável". Pra ilustrar, deu exemplos de produtos que mudaram seus mercados sendo memoráveis, como o iPod e o próprio Rails. Ele também mostrou, com dados estatísticos (inventados por ele), como existem mais oportunidades em Rails do que em Java ou PHP e que você ganhará muito dinheiro se for um expert, já que a imensa maioria dos programadores são apenas iniciantes. No geral, eu já tinha visto e lido o conteúdo da palestra dele muitas vezes, mas o jeito como ele apresenta que é sensacional, usando muito gráficos e vídeos, principalmente de video games.
Depois do almoço, fui ver a palestra de George Malamidis. Chegando lá, soube que Danilo Sato também participaria. Eu achei o conteúdo da palestra muito simples. Acho que era essa a intenção, mas não era o que eu esperava. Achei que veria conceitos avançados de REST, alguma integração com Rails, ou alguma outra coisa que eu não sabia. Basicamente, eles ensinaram o que era REST, e algumas coisas que poderia-se fazer com isso.
Depois disso, Dr Nic subiu no palco. Não achei a melhor palestra, mas com certeza ele é o melhor palestrante. Ele sabe como divertir uma platéia, mantê-la concentrada, e parece fazer tudo sem nenhum esforço. O sotaque australiano foi um pouco difícil de entender no começo, mas depois me acostumei. Ele falou muito bem sobre comunidades open-source, e porque você deve participar delas. E participar em qualquer nível, nem que seja só relatando um bug. Mostrou como essas coisas podem trazer benefícios concretos, inclusive financeiros. E brincou muito com as tradutoras :)
Depois de mais um Coffee Break, foi a vez de Chris Wanstrath. Apesar de gostar muito do que ele faz (mesmo sem contar o GitHub), o keynote dele foi muito frustrante. Ele apenas leu um texto, e que foi igual (exceto algumas palavras) ao que ele leu na Ruby Hoedown. Eu já tinha assistido na Confreaks, então fiquei fazendo outras coisas, na wi-fi (instável) do evento.
Após essa palestra, aconteceu o Birds of a Feather, a desconferência do evento. Teve alguns cases legais, algumas pessoas apenas mostrando seus sites, outros comentando sobre o software fechado das urnas eletrônicas. Mas todos concordam que a melhor coisa da BoF foi a apresentação de Elomar, que foi muito engraçada. Ele falou sobre grupos de estudos em geral, e focou um pouco na aprendendo-rails. Só não gostei dele dizendo que meu MacBook é bugado ¬¬
Comentários (1)