How can I reset a factory_girl sequence?

For googling people: without further extending, just do FactoryGirl.reload

FactoryGirl.create :user
#=> User id: 1, name: "user_1"
FactoryGirl.create :user
#=> User id: 2, name: "user_2"

DatabaseCleaner.clean_with :truncation #wiping out database with truncation
FactoryGirl.reload

FactoryGirl.create :user
#=> User id: 1, name: "user_1"

works for me on

* factory_girl (4.3.0)
* factory_girl_rails (4.3.0)

https://stackoverflow.com/a/16048658


Just call FactoryGirl.reload in your before/after callback. This is defined in the FactoryGirl codebase as:

module FactoryGirl
  def self.reload
    self.factories.clear
    self.sequences.clear
    self.traits.clear
    self.find_definitions
  end
end

Calling FactoryGirl.sequences.clear is not sufficient for some reason. Doing a full reload might have some overhead, but when I tried with/without the callback, my tests took around 30 seconds to run either way. Therefore the overhead is not enough to impact my workflow.


After tracing my way through the source code, I have finally come up with a solution for this. If you're using factory_girl 1.3.2 (which was the latest release at the time I am writing this), you can add the following code to the top of your factories.rb file:

class Factory  
  def self.reset_sequences
    Factory.factories.each do |name, factory|
      factory.sequences.each do |name, sequence|
        sequence.reset
      end
    end
  end
  
  def sequences
    @sequences
  end
  
  def sequence(name, &block)
    s = Sequence.new(&block)
    
    @sequences ||= {}
    @sequences[name] = s
    
    add_attribute(name) { s.next }
  end
  
  def reset_sequence(name)
    @sequences[name].reset
  end
  
  class Sequence
    def reset
      @value = 0
    end
  end
end

Then, in Cucumber's env.rb, simply add:

After do
  Factory.reset_sequences
end

I'd assume if you run into the same problem in your rspec tests, you could use rspecs after :each method.

At the moment, this approach only takes into consideration sequences defined within a factory, such as:

Factory.define :specialty do |f|
  f.sequence(:title) { |n| "Test Specialty #{n}"}
  f.sequence(:permalink) { |n| "permalink#{n}" }
end

I have not yet written the code to handle: Factory.sequence...