DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Single-table Inheritance And Validates_as_unique

11.29.2005
| 1947 views |
  • submit to reddit
        I had a User class, which then had a Moderator class.  I was using the "type" field in my database to denote whether a user was a User or a Moderator.  However, my validations weren't working as I expected:

validates_as_unique :name, :email

Users could have the same email address as Moderators.  Obviously sometimes this kind of scoping makes sense for STI classes, but it doesn't here.  I ended up writing this:

module ActiveRecord
  module Validations
    module ClassMethods
      # Intended for use with STI tables, helps ignore the type field
      def validates_overall_uniqueness_of(*attr_names)
        configuration = { :message => "must be unique" }
        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)

        validates_each(attr_names, configuration) do |record, attr_name, value|
          records = self.find(:all, :conditions=> ["#{attr_name} = ?", value])
          record.errors.add(attr_name, configuration[:message]) if records.size > 0 and records[0].id != record.id
        end
      end
    end
  end
end

This hastily named validation keyword allows you to specify fields you want to be considered unique across the entire table, whether they be Users, Moderators, Admins or MagicalPixies.  Now I just use:

validates_overall_uniqueness_of :name, :email