thoughtbot/shoulda-matchers — Issue #48: [Feature Request] Allow factories use in validate_uniqueness_of
Author: ppgengler
Created: 2012-01-26 17:19:36+00:00
State: open

Hi,

This is a feature request but I wasn't sure how to mark it as such with the Issue system. The basic idea is that once I'm using a factory system (factory_girl, machinist, etc.) its kinda silly that I'd have to write code per time I want to validate_uniqueness_of to create an object when I have a centralized definition of how to create objects. Ergo, it seems like it'd be pretty simple to allow validate_uniqueness_of to check for some type of factory system configuration (i.e. Should.factory_type = :factory_girl) and if set then try to use that factory system to create an object before executing the test.

I've implemented this specifically for factory_girl in my code base but since I'm in rails 2.3.x land still I didn't figure it was worth submitting a patch on the 1.3.3 branch of factory_girl, especially since the matchers moved out of the main gem, ergo the reason I opened this issue instead. When I make it to the latest branch of code I'm sure I'll patch that too, at which time I can submit a patch with tests and such, but in the meantime I thought I'd record the feature request, and include my current code in case anyone wants to a) use it themselves, or b) do the patch before I get to it. Here's the current helper code I added:

```
module Shoulda
module ActiveRecord
module Matchers
module ValidateUniquenessOfMatcherWithFactoryGirl
def self.included(base)
base.class_eval do
alias_method_chain :matches?, :factory_girl
end
end

# Use the subject to create a factory so that this passes correctly
def matches_with_factory_girl?(subject)
factory_name = (@factory_name || subject.class.to_s.underscore).to_sym
# TODO Throw a better message if the factory isn't defined, i.e. tell them to define one
Factory(factory_name)
matches_without_factory_girl?(subject)
end

# Allows specifying a factory for use with validate_uniqueness_of
# it {should validate_uniqueness_of(:foo).with_factory(:foo_in_special_state)
def with_factory(factory_name)
@factory_name = factory_name
self
end
end
end
end
end

Shoulda::ActiveRecord::Matchers::ValidateUniquenessOfMatcher.send(:include,
Shoulda::ActiveRecord::Matchers::ValidateUniquenessOfMatcherWithFactoryGirl)
```

Thanks,
\Peter