Sorry for opening an old thread but since it's 2011 and I still couldn't find a proper validator, I created one myself:
class UniqueSetValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
setup record
record.errors[attribute] << "- collection of fields [" + @fields + "] is not unique" if record.class.count(:conditions => @conditions) > 0
end
def check_validity!
raise ArgumentError, "Must contain an array of field names' symbols" unless options[:in] && options[:in].respond_to?(:each)
end
private
def setup record
conditions = []
fields = []
options[:in].each do |field|
conditions |= [ field.to_s + " = '" + record[field].to_s + "'" ]
fields |= [ field.to_s ]
end
@conditions = conditions.join(" AND ")
@fields = fields.join(", ")
end
end
It seems to work to me. To use it paste the code into:
your_rails_app/lib/unique_set_validator.rb
and enable it in:
your_rails_app/config/application.rb
by adding this line:
config.autoload_paths += %W( #{config.root}/lib )
Then you can simply use it in your model:
validates :field, :unique_set => [ :field, :field2 ]
It will validate the uniqueness of pair [ :field, :field2 ], and any error would be returned to :field. I haven't tried but it should work for more that 2 fields.
I hope that I didn't messed up anything, and that this will help someone. :)