Как вызвать валидаторы ActiveRecord как методы экземпляра (аля Sequel)? - PullRequest
3 голосов
/ 15 августа 2011

У меня есть модель, которой нужны разные валидаторы в зависимости от ее текущего состояния.Как мне следует вызывать валидаторы ActiveRecord для каждого экземпляра?Я хотел бы использовать как можно больше сантехники, но я не уверен, как продолжить.

class Order < ActiveRecord::Base
  attr_accessible :state

  validate :state_specific_validations

  def state_specific_validations
    if :paid == self.state
      # Warning: here be Unicorns...

      # Wishful thinking...
      validate_presence_of :paid_at
      validate_associated :purchaser

      # Hopeful. What are the validators called internally in Rails?
      errors << PresenceValidator.new(self, :paid_at).valid?
      errors << AssociationValidator.new(self, :paid_at).valid?

      # Plan B
      # ... Hoping for help from the audience ...

    else
      # Even more complicated validator logic, hoping for some DRY validators
    end
  end
end

Я мог бы просто использовать пользовательские валидаторы, но зачем мне дублировать все встроенныелогика валидатора (сообщения об ошибках i18n и т. д.)?

Есть ли аккуратный способ вызова валидаторов Rails как методов экземпляра?Я думаю, что подход Сиквела к валидаторам на основе экземпляров более разумен, чем к классам ActiveRecord, но я здесь не для того, чтобы судить.Я просто хотел бы вернуться к решению более интересных проблем.Я просто надеюсь, что другие сталкивались с этим и могут указать мне на какой-нибудь интересный смысл или драгоценность.

Ответы [ 2 ]

4 голосов
/ 15 августа 2011

Я почти уверен, что все методы validate_* могут иметь опцию :if - которая может указывать на другой метод (и, вероятно, также принимать Proc), так что вы можете разбить свои проверки, чтобы быть чем-то большим как:

validates_presence_of :paid_at, :if => :paid?
validates_association :purchaser, :if => :paid?

Для дальнейшей очистки есть помощник with_options:

with_options :if => :paid? do |v|
  v.validates_presence_of :paid_at
  v.validates_association :purchaser
end

Не уверен, что любой из них можно использовать со стандартным validate :custom_validate_method, но это меня не удивит.

0 голосов
/ 17 августа 2011

Есть ли причина, почему это неуместно? Кажется, это может сработать, но, возможно, метапрограммирование исказило мой мозг ...

class Order < ActiveRecord::Base
  attr_accessible :state

  validate :state_specific_validations

  def state_specific_validations
    if :paid == self.state
      class << self
        validate_presence_of :paid_at
        validate_associated :purchaser
      end
    end
  end
end

Хуже всего то, что тесты проходят, поэтому я не уверен, решил ли я это или мне нужны более качественные тесты. Например, я не уверен на 100%, что эта синглтон-модификация не влияет на другие ордера.

вздох Нужно немного поспать.

...