Callback vs validation
I created a callback when creating a new Client object instead of using the validates_u开发者_如何学Pythonniqueness_of
validation method because:
- I want to find the Client that already exists
- Add the existing Client details to my base error message
My question: is there a more elegant way of achieving this than my solution below?
I have the following model:
class Client < ActiveRecord::Base
before_validation_on_create :prevent_duplicate_clients
private
def prevent_duplicate_clients
client = self.class.find(:all, :conditions => ["first_name = ? AND middle_name = ? AND last_name = ? AND date_of_birth = ?", self.first_name, self.middle_name, self.last_name, self.date_of_birth])
if client.size >= 1
self.errors.add(:base, "Client exists as #{client.first.name}")
false
end
end
end
NB:
- Rails v2.3.5
If you want to take the custom validator path:
class Client < ActiveRecord::Base
validate :client_uniqueness
protected
def client_uniqueness
duplicates = self.class.all(:conditions => {
:first_name => first_name,
:middle_name => middle_name,
:last_name => last_name,
:date_of_birth => date_of_birth
})
if duplicates.present?
errors.add_to_base "Client exists as #{duplicates.map(&:name).to_sentence}"
end
end
end
You shouldn't put validation code in the before_validation callbacks. Change before_validation_on_create :prevent_duplicate_clients
to validate :prevent_duplicate_clients
There is no reason this can't be done in a validation. Via the validate
class method (Doc).
If you want a cleaner model, or are using this in multiple models it can be slightly DRYer by using a custom validator.
You could then have something like this
class Client < ActiveRecord::Base
validates_uniq_with_custom_message :first_name, :middle_name, :dob #etc
end
Here is a good blog on the subject
I think you're on the right track—my question would be whether you should add an error or simply add the details to the existing client.
精彩评论