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