0

O Dia em que parei de utilizar Fixtures

-

Ok, sempre vi por aí que o pessoal recomenda fortemente a utilização de factories de objetos ao invés de fixtures, porém as fixtures sempre serviram pra mim. Pelo menos até hoje.

O Problema comecou quando eu tive que sair da convenção do Rails. Tenho uma classe, digamos Customer, por exemplo, que possui dois Addresses:

class Customer < ActiveRecord::Base

has_one :business_address, :class_name => 'Address'
has_one :home_address, :class_name => 'Address'

end

Para os meus testes, criei os arquivos de fixtures

# addresses.yml

endereco_1:
street: Endereco 1

endereco_2:
street: Segundo Endereco

# customers.yml
rafael:
name: Rafael
business_address: endereco_1
home_address: endereco_2

Com as novas sexy fixtures, acreditei que isso seria possível. Porém, as fixtures, por natureza, refletem o que está no banco de dados, e nao nos objetos. Não importa que a minha classe Customer tenha atributos business_address e home_address mapeando para a classe Address, o sistema de fixtures não irá conseguir vincular o meu endereco_1 e endereco_2 com o customer rafael. Eu teria que criar uma fixture da seguinte forma:

# customers.yml
rafael:
name: Rafael
business_address_id: 1
home_address_id: 2

E com isso, perder toda a legibilidade. Imagina a bagunça que ficaria se todas as associações do meu modelo fossem com os ids. Quem conseguiria entender além do computador ?

Foi por isso que decidi utilizar o factory_girls. Com ele é possível fazer este tipo de associação sem ter que ficar fazendo macumba gambiarra workarounds. Após a instalação da gem, e configuração (que pode ser vista aqui), basta criar um factories.rb da seguinte forma:

Factory.define :endereco_1, :class => Address do |a|
a.street "Endereco 1"
end

Factory.define :endereco_2, :class => Address do |a|
a.street "Endereco 2"
end

Factory.define :rafael, :class => Customer do |c|
c.association :business_address, :factory => endereco_1
c.association :home_address, :factory => endereco_2
end

E no seu teste:

rafael = Factory(:rafael)

Simples, não ? E bem melhor…

0

Ruby Smart Snippet

-

Uma das coisas que mais gosto em Ruby é o fato da linguagem mudar a sua forma de pensar. Por exemplo, olhe o código abaixo:

foobar = FooBar.find(:first)
if foobar.age >= 18
  puts 'Olá, você é maior de idade'
end

Mas, como você já é um programador experiente, sabe que foobar pode ser nulo (nil) e com isso ter problemas com o código acima. Desta forma você faria:

foobar = FooBar.find(:first)
if foobar && foobar.age >= 18
  puts 'Olá, você é maior de idade'
end

Desta forma você garante que só irá chamar foobar.age se foobar não for nulo. Mas, tem um jeito muito mais Ruby Way de se fazer isso. Olhe só o que encontrei neste post:

class NilClass
  def maybe(*a); self; end
end

class Object
  alias :maybe :send
end

age = FooBar.find(:first).maybe(:age)

Dessa forma, se FooBar.find(:first) retornar nulo, .maybe(:age) irá retornar nulo, ao invés de um erro falando que a Classe Nil não tem o “método” .age. Evidentemente isto não irá revolucionar a vida de ninguém, mas é apenas um exemplo de como podemos explorar o novo paradigma que ruby trouxe.

2

The Ruby way…

-

Hoje estou estreando uma nova categoria no meu blog. É a categoria RUBY! Aqui irei abordar assuntos, dicas, curiosidades e boas práticas para a linguagem ruby, bem como para o rails. E para facilitar o acompanhamento dessa nova “thread”, criei um novo Feed, que direciona diretamente para cá. Portanto se você quer ler apenas o conteúdo ruby, do meu blog, assine o este feed.

Para começar, mostrarei um exemplo de como pode ser simples a soma de todos os elementos de um array:

meu_array = [1,2,3,4,5,6,7,8,9,10]
meu_array.inject {|acumulador, valor_corrente| acumulador + valor_corrente}

Simples, não ? Mas atente aqui para a função inject. O nome dela parece ser meio ingrato, mas o que ela faz é iterar um array e ir “injetando” o acumuladorno bloco a cada interação. Com o ruby 1.8.7, será possível fazer:

meu_array = [1,2,3,4,5,6,7,8,9,10]
meu_array.inject(:*)

Para multiplicar todos os elementos de um array sem passar um bloco.