O problema que este artigo vai tentar detalhar é "upload e processamento de imagens". Algo simples como subir uma foto no seu perfil. Assumindo que todos já leram meus artigos sobre o Heroku é hora de mais uma dica muito importante.

Arquitetura Mais Comum

Neste exemplo de ilustração vemos o que a maioria das pessoas iniciando implementa:

  1. Seu browser terá um form multipart e um campo file para escolher um arquivo de imagem e fazer o POST para seu controller do lado Rails

  2. O servidor web recebe o arquivo inteiro primeiro (ex. NGINX) e só então passa pra aplicação. Seu controller recebe esse arquivo, instancia o model adequado com um uploader de Carrierwave montado. O uploader inicia o processamento das imagens, digamos, 5 versões de tamanhos diferentes, usando ImageMagick.

  3. Opcionalmente, o uploader faz o upload das novas versões ao AWS S3. Finalmente, retorna ao controller que tudo deu certo e o controller, por sua vez, devolve uma página de sucesso ao browser.

Este é um artigo bem curto para uma dica que é útil tanto para quem está começando como para quem cria muitos projetos o tempo todo. Todos conhecemos o bom e velho comando rails new novo_projeto que vai criar uma estrutura padrão de projetos. Porém, poucos de nós realmente usamos a estrutura padrão, sempre precisamos de muito mais hoje em dia. Em virtude desse requerimento, o Rails suporta um arquivo de templates onde você pode modificar o comportamento do rails new logo em seguida. Mas esse arquivo é um script chato de manter, chato de configurar.

Em vez disso podemos usar uma outra ferramenta que existe há algum tempo chamado Rails Composer. Assumindo que você já tenha RVM ou Rbenv instalado e configurado:

1
2
gem install rails
gem install rails_apps_composer

Ano passado, quando um projeto de cliente entrou em produção, ter esquecido disso me custou várias horas de muita tensão. Graças à ajuda rápida e precisa da equipe de suporte e desenvolvimento do Heroku (thanks @ped) conseguimos contornar a situação.

O Heroku continua sendo minha recomendação a todos os meus clientes. A menos que você tenha uma situação presente muito particular (e lhes garanto, são casos raros), 99% dos casos cabem como uma luva no Heroku. Portanto, na dúvida, vá de Heroku.

Porém, o Heroku tem algumas peculiaridades que você precisa conhecer. Caso ainda não tenha visto, reveja meu artigo Enciclopédia do Heroku que publiquei em Abril de 2012.

Análise estática de qualidade de código executado automaticamente é uma daquelas coisas que quando você se acostuma a usar passa a pensar "como diabos eu sobrevivia antes sem isso?"

Se ainda não conhece, trate de experimentar o excelente Code Climate criado por Bryan Helmkamp, um rubista muito conhecido na comunidade por contribuições em diversos projetos open source, incluindo o próprio Rails e bibliotecas que já foram muito usadas algum tempo atrás como webrat.

O que o Code Climate faz é muito simples: você cadastra seu projeto público ou privado do Github e ele vai começar a processá-lo até surgir com uma nota que vai de zero a quatro. Eu ainda não vi como é um projeto nota Zero mas considerando que já trabalhamos em alguns projetos de resgate que começou em notas como 2 - e já era lamentável - zero significa "mude de profissão, você não serve para isso."

Veja um dos meus projetos de cliente (e todo projeto de cliente tem o mesmo nível):

Nota de todo projeto de cliente no Code Climate

Feliz Ano Novo. Vamos ao primeiro post de 2014 :-)

Conforme prometido, o Ruby Core Team nos entregou seu presente de Natal no dia 25/12/2013. A versão 2.1 do Ruby foi lançado oficialmente.

Se usa RVM basta instalar com rvm install ruby-2.1.0.

Se usa rbenv com ruby-build basta instalar com rbenv install 2.1.0.

A versão TL;DR é o seguinte: se o que você está programando funciona com Ruby 1.9.3 ou com Ruby 2.0.0, muito provavelmente vai funcionar com Ruby 2.1.0. Cada uma delas tem novas funcionalidades em relação à anterior, mas elas não quebram a compatibilidade a ponto de quebrar.

Se sua aplicação utiliza Bundler modifique sua Gemfile para ter a seguinte linha:

1
ruby '2.1.0'

Eu utilizo RVM e quando entro num projeto com uma Gemfile já associada a um Ruby ele automaticamente escolhe a versão certa. Ou mude manualmente como rvm 2.1.0 ou rbenv local 2.1.0. A partir disso rode o bom e velho comando bundle para instalar as gems novamente nesta nova versão de Ruby. O resto é a mesma coisa. Se tudo der certo, você não deve notar nada de diferente.

Ontem o @Fgrehm mandou no nosso Campfire sobre o projeto rails-assets.org. Ele acabou de ser lançado, portanto não pode ser considerado mais que um "beta". Ela pode ser tanto a salvação da lavoura para front-ends em projetos Rails ou não, na prática ainda não sabemos.

O @jcemer publicou hoje um ótimo post explicando isso do ponto de vista de um front-end full-time, colocando em perspectiva.

Em resumo, o Rails trás um mecanismo fantástico chamado Asset Pipeline. Ele tem diversas funções, em particular otimizar os assets dos projetos Rails, compilando fontes de Sass ou Less para CSS. Depois concatenando todos os CSS, JS em um único arquivo. Depois minificando (com Uglify) para diminuir seu tamanho. Em particular com Sass ele ainda pode concatenar sprites em uma única imagem também. Enfim, o pacote completo para otimizar assets ao máximo.

Se você ainda não conhece sobre esse recurso, não deixe de ler meu tutorial.

Estou um pouco atrasado, mas para quem não sabia recentemente aconteceu o Rubyconf 2013 em Miami. Todas as palestras estão gravadas e disponíveis pela excelente Confreaks.

Estava assistindo as Lightning Talks que foi bem longa (mais de 2 horas!) e selecionei as que foram realmente práticas. Veja minhas favoritas na lista a seguir. Clique no link do tema para ir direto na posição certa no vídeo do YouTube˜ para não perder tempo.

Ruby on Rails é definitivamente o primeiro motivo para qualquer novo programador se interessar por Ruby. É um framework muito estável que conquistou uma posição de destaque. Atualmente criou-se um ecossistema que expandiu além do framework e gerou uma coleção de bibliotecas, ferramentas e serviços. O pacote básico oferece muito: desde um excelente suporte a MVC-Web. O sistema de roteamento ainda é excepcional mesmo comparado a outros frameworks. Apesar de controverso o ORM ActiveRecord evoluiu e se tornou muito estável. Novos patterns de organização como Presenters, Service Objects, Concerns surgiram para facilitar aplicativos maiores. Pacotes como Minitest, RSpec, Factory Girl, Fabricator e outros continuam a tornar os testes mais e mais completos. Também controverso o Asset Pipeline faz o que todo framework deveria fazer como básico: minificar e otimizar assets.

O mundo front-end evoluiu além do JQuery. É trivial integrar os novos frameworks como Backbone, Angular, Ember. O mundo de CSS também evoluiu além do Sass, temos facilmente integrado Twitter Bootstrap, Foundation e outros. E o mundo de templates evoluiu além do ERB e HAML com exemplos como Slim. Enfim, existem opções simples para todos os gostos.

Este artigo é mais uma anotação para mim mesmo mas deve servir para mais pessoas também. Se você ainda não sabe o que é Vagrant, leia o artigo do Nando Vieira "Usando o Vagrant como ambiente de desenvolvimento no Windows" ou assista a palestra que ele deu na Rubyconf Brasil 2013.

Assumindo que você já sabe o que é Vagrant, resolvi explorar mais algumas de suas opções. Em particular, como subir uma nova máquina e automatizar sua configuração. Existem algumas formas, a mais simples é provisionamento via shell-scripts a mais interessante é o provisionamento usando Chef-Solo. Existem também as opções com Ansible e Puppet.

Se você já fez deployments usando Heroku, uma coisa que pode ter parecido estranho no começo e agora já é segunda natureza é colocar configurações específicas de ambiente em variáveis de ambiente ("env").

No caso do Heroku, podemos fazer:

1
heroku config:add HELLO_WORLD=true

E dentro da aplicação podemos pegar esse valor com

1
ENV['HELLO_WORLD']

O problema: e quando estamos desenvolvendo? #comofaz?

Se ainda não leu, dê uma olhada sobre o que já postei como dicas de Heroku e minha opinião sobre o serviço.

Recentemente tentei subir um projeto Rails 4 bem simples no Heroku e encontrei problemas logo na primeira tentativa de deploy. O problema é o seguinte: a forma mais aceita de configurar uma aplicação é usar variáveis de ambiente (veja projetos como o dotenv-rails). No primeiro deploy essas variáveis não estão disponíveis, em particular o DATABASE_URL. Na task assets:precompile não deveria haver nada na inicialização que dependesse de conexão ao banco, mas algumas gems ainda não estão corrigidas dessa forma, em particular duas com esse bug já conhecido são o active_admin e o acts-as-taggable-on.

Aproveitando o artigo Usando associações de ActiveRecord incorretamente que acabei de publicar, vamos dar mais uma dica que mencionei na seção de Bônus: editar múltiplos objetos ActiveRecord num mesmo formulário.

Muitas vezes você tem o cenário ontem possui um objeto Pai e múltiplos objetos Filhos no ActiveRecord, seriam formatos como Lista de Compras e produtos, Perguntas e Respostas, Projeto e Atividades. Se usar o scaffold normal do Rails vai acabar criando telas separadas para cada recurso. Mas e se quisermos editar os atributos do Pai e dos filhos tudo no mesmo formulário?

O Rails possui um recurso chamado Nested Attributes onde você pode passar os atributos dos objetos filhos diretamente no objeto Pai. Parafraseando a documentação oficial poderíamos ter algo como:

Nos últimos dias, trabalhando num projeto legado, encontrei uma situação que me fez perder pelo menos um dia inteiro. É uma situação que já vi algumas outras vezes e que achei interessante explicar para que ninguém mais caísse no mesmo problema.

TL;DR

Pense numa associação muito básica:

1
2
3
4
5
6
7
class ShoppingList
  has_many :shopping_items
end

class ShoppingItem
  belongs_to :shopping_list
end

Se você não souber como associações funcionam, poderia começar pensando da seguinte forma:

1
2
3
lista = ShoppingList.first        # pega uma lista
item = lista.shopping_items.first # pega um item dessa lista
lista2 = item.shopping_list       # a partir do item pega a mesma lista

Caso ainda não saiba, o bom e velho Ruby 1.8 desempenhou seu papel muito bem nos últimos anos e chegou a hora de aposentá-lo. Ele não receberá mais manutenção ou mesmo correções de segurança a partir de Junho deste ano (2013). Significa que seu irmão-gêmeo, o venerado Ruby Enterprise Edition 1.8.7, que nos apresentou a funcionalidade de Copy-on-Write e a possibilidade de refinar os parâmetros do garbage collector, também ser tornará obsoleto em breve.

O que acontece hoje é que existem muitos aplicativos ainda rodando em Ruby MRI ou REE 1.8.7, desenvolvido em Ruby on Rails 2.3, em produção, que ninguém sabe o que deve fazer. A resposta mais comum, caso pergunte aleatoriamente a um desenvolvedor, será "reescrever" em Ruby 2 e Ruby on Rails 3.2 (ou já arriscando para o Rails 4.0 que sairá em breve).

Minha resposta é diferente: se seu aplicativo está hoje em produção, com usuários acessando, minha primeira opção sempre será explorar a possibilidade de realizar o que chamamos de "migração técnica". Uma migração técnica:

  • não envolve mudar funcionalidades ou criar novas;
  • no máximo retirar funcionalidades desnecessárias;
  • e apenas realizar a atualização para as versões mais recentes de Ruby e Rails.

Uma das gems que eu mais uso em projetos é o ActiveAdmin, de todas as opções de admin para Rails que surgiram até hoje, esta foi a que melhor se adaptou na maioria dos projetos. Longe de ser perfeita, mas o suficiente para atender bem as necessidades de uma simples coleção de CRUDs.

Outra vantagem é que pouco a pouco um pequeno ecossistema surgiu em torno do framework, adicionando funcionalidades como granularidade de permissões com CanCan, e eu já bloguei sobre sua excelente integração com o Best in Place. Desta vez experimentei outra extensão que gostei muito, o ActiveAdmin-WYSIHTML5.

ActiveAdmin-Dragonfly

Muitos instalam e mantém seu próprio servidor num VPS. Uma aplicação web hoje é formada por diversos componentes como o web server (NGINX), banco de dados (PostgreSQL, Redis), workers de fila (Resque ou Sidekiq), serviços agregados (como SOLR).

Como já disse antes, fazer "rodar", é simples. Agora e se o processo der crash por alguma razão ou o servidor reiniciar?

Upstart

Monit

Atualizado 7/5/2013: adicionado procedimento que não existe na documentação oficial para conseguir fazer deployments "corretamente" no Appfog.

Como disse antes comecei a usar o AppFog pra várias coisas. Mas tem um problema, diferente do Heroku ele não é bom pra executar assets:precompile (primeiro porque pode estourar memória, segundo porque dá timeout se o processamento demorar muito).

O processo de deployment não é via git push mas via o comando af update. Ele simplesmente faz um upload dos arquivos no diretório do projeto ao servidor (se entendi direito). Portanto o melhor a fazer é executar o assets:precompile localmente antes do deploy (lembrar de colocar turbo-sprockets pra ir mais rápido).

O problema é que agora em modo de desenvolvimento o servidor local vai começar a puxar os assets direto da pasta public/assets em vez de processar dinamicamente da pasta app/assets que é o que você precisa em desenvolvimento. Vide meu artigo Asset Pipeline para Iniciantes caso ainda não esteja bem familiarizado com o processo.

Rackspace

Linode

WebbyNode

A opção mais antiga, antes de existirem os Platform as a Service (PaaS) como Heroku, AppFog, OpenShift e outros são os Virtual Private Servers ou VPS. Os termos confundem pois costumamos chamar de "cloud" as soluções que caem nas categorias SaaS (serviços), PaaS (plataforma), IaaS (infraestrutura) e muitos tendem a deixar VPS numa categoria à parte.

VPS são máquinas virtuais, assim como um VirtualBox, Parallels, VMWare na sua máquina local, só que hospedado no data center de alguém. Eu particularmente acho que VPS está na mesma categoria que IaaS.

Outra coisa que muita gente se confunde: "preciso do meu próprio servidor, instalado do zero, porque tenho vários serviços não-web que preciso instalar e manter na mão, como SOLR, postfix, etc"

Não, a menos que você tenha uma operação grande, não precisa. Utilize os diversos Software as a Service (SaaS) que existem. Muitos deles oferecem planos gratuitos para pouca utilização - pois obviamente, se você vai utilizar bastante é porque sua aplicação fatura o suficiente pra pagar a infraestrutura, caso contrário porque investir nela?

SaaS

Como disse no artigo anterior, na dúvida, use o Heroku. Mas depois disso, alguns perguntam se existem outras alternativas. De fato existem várias. Agora é a vez de outra opções, o AppFog foi uma das mais interessantes que usei.

Appfog

Ela tem algumas características semelhantes e outras diferentes do Heroku. Vamos a alguma delas:

Muitos ainda devem ter dúvidas de onde colocar suas aplicações Rails. Nos últimos dias andei testando algumas alternativas.

Na prática está entre as opções:

  1. Instalar do zero seu próprio servidor e se responsabilizar pela manutenção
  2. Usar um PaaS (Platform as a Service) e deixar um serviço cuidar da infraestrutura por você

Em ambas as opções as peças mais importantes são:

  1. servidor web (nginx, apache2)
  2. banco de dados (SQL: PostgreSQL, MySQL; NOSQL: MongoDB, CouchDB, Redis, Riak), incluindo facilidade em escalar verticalmente (mais CPU/RAM) e horizontalmente (replicação)
  3. load balancer (HAProxy), incluindo facilidade em aumentar os servidores web
  4. opcionais (Memcached)
  5. manutenção (aplicação de patches de segurança, backup)

Heroku

No próximo artigo vou falar de outra opção que estou gostando, o AppFog, mas no geral o PaaS que oferece o melhor balanço entre funcionalidades, facilidade, serviços ainda é o Heroku. Se ainda não viu, leia meu artigo Enciclopédia do Heroku. A grande vantagem é realmente preocupação perto de zero com infraestrutura.