Tuesday 10 July 2012

Foolproof FactoryGirl Sequence

Turns out Sequencing in FactoryGirl isn't as easy as it used to be.
Factory.next has been deprecated and the two obvious ways to make a sequence now throw Trait error or Attribute already defined error "FactoryGirl::AttributeDefinitionError"

The problem with this first approach is name. In a normal sequence you would just say name but I want to use it in the description too. This somehow makes FactoryGirl believe name is a trait.

FactoryGirl.define do
  
  sequence(:code) {|n| "#{n+1000}"}
  
  factory :course do |u|
    name "CS#{ generate :code }"
    description "#{name}, 1st year, 1st semester, Foundation Of #{name}"
  end
end

This next example has a problem with the description line. This causes the description to generate 2 more names and throw an AttributeDefinitionError because you now have more than 1 name generated.
For some reason you cannot get around it by making the name line name = Factory.generate :name because name becomes a Trait again.

FactoryGirl.define do
  
  sequence(:name) {|n| "CS#{n+1000}"}
  
  factory :course do |u|
    name
    description "#{name}, 1st year, 1st semester, Foundation Of #{name}"
  end
end

This is the only thing that works. Static forcing FactoryGirl to use the already defined name again using the |a| block in description. It isn't as pretty as it could be but I have to live with it unless someone can tell me a better way. There is probably a solution where you use an after_build tag but that makes it longer and more complicated unnecessarily and it would still be ugly.

FactoryGirl.define do
  
  sequence(:name) {|n| "CS#{n+1000}"}
  
  factory :course do |u|
    u.name
    u.description {|a| "#{a.name}, 1st year, 1st semester, Foundation Of #{a.name}"}
  end
end

No comments:

Post a Comment