Question

I am working on a Rails 3 app that is needing to run a validation on a virtual field to see if the record already exists... here is my model code:

      #mass-assignment
      attr_accessible :first_name, :last_name, :dob, :gender

      #validations
      validates_presence_of :first_name, :last_name, :gender, :dob
      validates :fullname, :uniqueness => { :scope => [:dob] }

def fullname
    "#{first_name} #{last_name}"
  end

I am not getting any errors, its passing the validation.

Était-ce utile?

La solution

I don't think you can do something like that with standard validates. Reason is, it usually is a "simple" sql look-up for uniqueness. But to check uniqueness of what's sent back from your method, it'd have to :

  • Get all entries of your scope
  • For each, execute the fullname method.
  • Add every result in an array while testing for uniqueness

Simple when the data set is small, but then it'd just take ages to do as soon as you reach 10K plus matches in your scope.

I'd personally do this with a standard before_save using the dob scope

before_save :check_full_name_uniqueness

def check_full_name_uniqueness
  query_id = id || 0
  return !Patient.where("first_name = ? and last_name = ? and dob = ? and id != ?", first_name, last_name, dob, query_id).exists?
end

Add error message (before the return):

errors.add(:fullname, 'Your error')

Back in the controller, get the error :

your_object.errors.each do |k, v| #k is the key of the hash, here fullname, and v the error message
  #Do whatever you have to do
end
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top