2011-07-06 3 views
1

Я создал функцию обратного вызова при создании нового объекта клиента вместо того, чтобы использовать метод validates_uniqueness_of проверки, потому что:Обратный вызов против проверки

  • Я хочу, чтобы найти клиента, который уже существует
  • Добавить существующую информацию клиента к моему базовое сообщение об ошибке

Мой вопрос: есть ли более элегантный способ достижения этого, чем мое решение ниже?

У меня есть следующий модель:

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

ответ

1

Вы не должны указывать код проверки в обратных вызовах before_validation. Изменение before_validation_on_create :prevent_duplicate_clients - validate :prevent_duplicate_clients

+0

& @CaptainPete: Если я переведу свой callback на 'validate', это не будет вызвано для создания и обновления методов, так как я хочу, чтобы это произошло для новых записей – Coderama

+2

, вы можете передать: on =>: create to the validate class macro – paukul

+1

Однако я бы избавился от получения результатов из базы данных и вместо этого использовал счет. Получение результатов не требуется, потому что вы уже знаете, что такое значение, скажем, имя fist_name, поскольку вы проверяете уникальность. – paukul

2

Если вы хотите, чтобы идти по пути валидатора:

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 
+0

Не так ли лишний раз? '# {duplicates.map (&: name) .to_sentence}' Поскольку, если эта проверка всегда соблюдается, не будет многократных дубликатов. – diedthreetimes

+0

Да. Он демонстрирует один из моих любимых помощников ActiveSupport и ярлыков Ruby! Я решил, что @Coderama заменит все, что нужно в контексте. – captainpete

+0

@diedthreetimes Очень хорошая точка. В большинстве случаев можно было бы проверить, что данные были чистыми в соответствии с этой проверкой, чтобы проверить это предположение, прежде чем записывать его. В этом случае я только предположил, что данные грязные. – captainpete

1

Нет причин, по которым это невозможно сделать при проверке. С помощью метода класса validate (Doc).

Если вы хотите использовать более чистую модель или используете ее в нескольких моделях, это может быть немного DRYer с помощью специального валидатора.

Вы могли бы иметь что-то вроде этого

class Client < ActiveRecord::Base 
    validates_uniq_with_custom_message :first_name, :middle_name, :dob #etc 
end 

Вот хороший blog на тему

0

Я думаю, что вы на правильном пути-мой вопрос будет ли вы должны добавить сообщение об ошибке или просто добавьте детали к существующему клиенту.

Смежные вопросы