module MongoMapper module Plugins module Validations def self.configure(model) model.class_eval { include ActiveModel::Validations } end module DocumentMacros def validates_uniqueness_of(*args) validates_with MongoMapper::Plugins::Validations::UniquenessValidator, _merge_attributes(args) end end class UniquenessValidator < ActiveModel::EachValidator def initialize(options) super(options.reverse_merge(:case_sensitive => true)) end # Unfortunately, we have to tie Uniqueness validators to a class. def setup(klass) @klass = klass end def validate_each(record, attribute, value) # finder_class = find_finder_class_for(record) # table = finder_class.unscoped # # table_name = record.class.quoted_table_name # sql, params = mount_sql_and_params(finder_class, table_name, attribute, value) # # relation = table.where(sql, *params) # # Array(options[:scope]).each do |scope_item| # scope_value = record.send(scope_item) # relation = relation.where(scope_item => scope_value) # end # # unless record.new_record? # # TODO : This should be in Arel # relation = relation.where("#{record.class.quoted_table_name}.#{record.class.primary_key} <> ?", record.send(:id)) # end # # if relation.exists? # record.errors.add(attribute, :taken, :default => options[:message], :value => value) # end # value = instance[attribute] # return true if allow_blank && value.blank? # base_conditions = case_sensitive ? {self.attribute => value} : {} where_conditions = {} where_conditions[attribute] = /#{record[attribute].to_s}/i doc = record.class.first(where_conditions) record.errors.add(attribute, :taken, :default => options[:message], :value => value) unless doc.nil? || record._id == doc._id end end end end end