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…