Over a million developers have joined DZone.

Single-table Inheritance And Validates_as_unique

·
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


Topics:

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}