开发者

Callback vs validation

开发者 https://www.devze.com 2023-03-18 22:53 出处:网络
I created a callback when creating a new Client object instead of using the validates_u开发者_如何学Pythonniqueness_of validation method because:

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消