Marcio Trindade

Ruby

Problemas com campos inet no Rails

A partir do Rails 4 podemos utilizar campos específicos do PostgreSql com está descrito no Rails Guide. Um destes campos que resolvi utilizam ontem foi o campo inet que representa um host ou uma rede com IPv4 ou IPv6. Sendo assim podemos armazenar registros de range de IPs como por exemplo 192.168.0.0/24.

Como podemos ver no Pull Request #6196 o Rails converte este tipo de campo no objeto IPAddr do ruby então vamos entender como este objeto funciona. Vamos começar pelo range de IPs 192.168.0.0/32 que podemos entender que o 192.168.0.0 representa o IP e o /30 representa o prefixo. Quando instanciamos um objeto IPAddr com este range de IP o mesmo deixa de utilizar o prefixo e passa a utilizar uma representação com máscara 255.255.255.252, veja o exemplo abaixo.

ruby
IPAddr.new('192.168.0.0/30')
# => #<IPAddr: IPv4:192.168.0.0/255.255.255.252>

Depois que instanciava o Objeto não consegui mais representar o mesmo através de ip/prefixo, assim quando criei um formulário eu podia entrar com o valor de um range, mas ao editar o mesmo ele me trazia somente o IP e ignorava o prefixo. Olhando o código do Rails vi que como é feito a representação ip/prefixo que é salva no banco e é como eu precisaria mostrar no formulário de novo, então passei a utilizar o mesmo código na minha aplicação.

Após alguns testes observei um outro problema, quando eu altero somente o prefixo de um range o Rails não salva esta alteração no banco e entendi que o problema está no jeito como o IPAddr trata a comparação entre os objetos. Para este tipo de objeto a comparação é feita somente com o IP e ignorado o prefixo como podemos ver no código abaixo.

ruby
IPAddr.new('192.168.0.0/24') == IPAddr.new('192.168.0.0/30')
# => true

Tendo isso em mente e entendendo o Dirty Models do Rails ficou fácil perceber por que quando altero somente o prefixo o novo valor não é salvo no banco de dados. Então pra solucionar este segundo problema utilizo o método attribute_will_change! (no meu caso address_will_change!) para informar o Rails que precisa salvar este no banco sempre.


Utilize o Gmail para todas suas contas

O assunto de hoje é um "off topic" que vale a pena comentar aqui, eu tenho mais de uma conta de email e no caso esta segunda, que vou chamar de conta "X", não é um gmail. Logo eu não consigo utilizar a interface web do google.

Por que utilizar a interface do Gmail.

  • Pra mim é muito melhor do que todos os clientes de email que já utilizei;
  • Não utiliza espaço no meu SSD;
  • Está disponível pra qualquer computador, tablet ou telefone;
  • Possui uma busca incrível e muito rápida;
  • Tem a melhor organização que conheço (multi-labels).

Tendo isso em mente tentei de algumas formas receber os meus emails da conta "X" na caixa de entrada do Gmail e não consegui, foi então que pensei em uma solução que resolveria os meus problemas, decidi escrever uma aplicação simples em Ruby que conecta na conta "X" copia os emails pra conta do Gmail e depois apaga o email da conta "X".

A idéia é bem simples e tem funcionado pra mim a mais de 6 meses, por isso resolvi compartilhar para que mais pessoas que prefiram utilizar o gmail possam o fazer também.


A nova sintaxe de mocks do rspec

No último artigo escrevi sobre a nova sintaxe do rspec, agora vou falar sobre a nova sintaxe para os mocks do rspec. Veja a documentação.

Apartir do rspec 2.14.0 as duas sintaxes estão presentes e você pode especificar qual deseja usar no spec_helper.

spec_helper.rb
RSpec.configure do |config|
  config.mock_with :rspec do |c|
    # c.syntax = [:expect, :should]
    # c.syntax = :should
    c.syntax = :expect
  end
  config.expect_with :rspec do |c|
    # c.syntax = [:should, :expect]
    # c.syntax = :should
    c.syntax = :expect
  end

A nova sintaxe do rspec

O Rspec agora possui uma nova sintaxe que ao meu ponto de vista ficou um pouco mais coeso com o que realmente o teste está testando.

Pra configurar é bem simples, basta você setar qual modo deseja usar no seu spec_helper.

spec_helper.rb
RSpec.configure do |config|
  config.expect_with :rspec do |c|
    # c.syntax = [:should, :expect]
    # c.syntax = :should
    c.syntax = :expect
  end
end

Acredito que o código acima é auto explicativo e não se faz necessário explicações.


Utilizando gems locais em desenvolvimento

Hoje encontrei uma dica muito útil no site The Life of a Radar.

Quem utiliza alguma gem na qual está trabalhando constantemente sabe como é chato ficar alterando o arquivo Gemfile sempre que vai fazer um deploy. Este é o meu caso que tenho os models do meu projeto separado em uma gem (Rails Engine) a fim de reutiliza-los em todos os projetos, tanto front-end quanto workers.

Como a maior parte do tempo estou desenvolvendo, mantenho o meu Gemfile configurado desta forma:

Gemfile
gem 'projet-models', path: "../project-models"

Começando com Mongoid

Hoje quero mostrar algo muito simples, mas é pra encorajar as pessoas que ainda não usaram o MongoDB como banco de dados de seus projetos.

É importante você conhecer pelo menos um pouco do mongodb, saber como instalar, iniciar, parar, reiniciar, fazer uma query e inserir e editar documentos.

Depois que já tiver este background então vale a pena dar uma olhada na página do Mongoid, que é uma ótima gem criada pelo Durran Jordan pra trabalhar com mongodb no rails.


Pjax

Não faz muito tempo que escutei falar de pjax uma técnica que une ajax + pushState e que o Chris Wanstrath do github difundiu criando o jquery-pjax, recentemente o Ryan Bates do railscts.com publicou um epsódio mostrando como você pode utiliza-la com o rails.

Você já deve ter visto a arvore de códigos (source tree) que o github utiliza, quando você clica em um arquivo ou diretório ele atualiza o conteúdo via ajax e altera a url pra que você possa copiar e mandar pra outras pessoas sem o uso de ancoras que hoje em dia é o uso comum. Isso mantém o histórico de navegação dos navegadores funcionando.


Nginx + Unicorn

Desde que a Phusion lançou o passenger eu sempre o utilizei em conjunto com o apache que já era familizarizado.

Quando trabalhei na Digital Pages me deparei com o pessoal utilizando o passenger com nginx, pra falar a verdade eu só tinha escutado falar deste servidor web e nem dei muita bola, além de que a aplicação caia de tempos em tempos e o log ficava poluído com algumas mensagens que o passenger adicionava, mostrei para o pessoal como utilizar o apache no lugar do nginx, a aplicação acabou ficando bem estável e optamos por colocar em produção.


Introdução ao Guard

Dando continuidade aos últimos artigos resolvi escrever sobre a Guard, uma gem que complementa de forma incrível o uso do spork e automatiza seus testes.

A Guard tem uma função parecida com a Watcher, que praticamente fica monitorando alterações em seus arquivos e pode executar deterinadas ações quando isso ocorre, porém ele é bem estruturado e aceita outras gems complementares pra facilitar nosso dia a dia, uma destas é a guard-rspec e a guard-spork.


ActiveReload pra melhorar a performance de projetos rails

Embalado um pouco com o último post que era pra melhorar a performance do seus test vou falar um pouquinho de outra gem que também melhora a performance, mas agora em modo de desenvolvimento.

A Gem ActiveReload do Robert Pankowecki faz uma boa diferença em projetos grande com muitos arquivos, pois quando você sobe um servidor em modo de desenvolvimento ele carrega todos os arquivos como se fosse no modo de produção e quando você alterar suas classes ele faz o reload somente dos arquivos alterados, logo o tempo pra de carregamento das páginas diminui bastante. É compatível com ruby >= 1.8.7 e já foi testado com rails >= 3.0.10.