Пользовательские проверки на рельсы - PullRequest
3 голосов
/ 18 февраля 2011

Я хотел бы знать, есть ли способ использовать проверки рельсов для настраиваемого действия.

Например, я хотел бы сделать что-то вроде этого:

validates_presence_of :description, :on => :publish, :message => "can't be blank"

Я делаю базовые проверкисоздавать и сохранять, но есть очень много вещей, которые я не хочу требовать сразу.Т.е. они должны иметь возможность сохранять пустые записи без проверки всех полей, однако у меня есть пользовательское действие и состояние «опубликовать» в моем контроллере и модели, которые при использовании должны проверять, чтобы убедиться, что запись равна 100%

Приведенный выше пример не сработал, есть идеи?

ОБНОВЛЕНИЕ:

Мой конечный автомат выглядит так:

  include ActiveRecord::Transitions
  state_machine do 
    state :draft
    state :active
    state :offline

    event :publish do
      transitions :to => :active, :from => :draft, :on_transition => :do_submit_to_user, :guard => :validates_a_lot?
    end

  end

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

Ответы [ 2 ]

5 голосов
/ 18 февраля 2011

Для меня это больше похоже на бизнес-логику, чем на проверку модели.Несколько лет назад я участвовал в проекте, в котором мы должны были публиковать статьи, и именно в этот момент было применено множество бизнес-правил.

Я бы предложил вам сделать что-то вроде Model.publish () иэтот метод должен обеспечивать соблюдение всех бизнес-правил для публикации элемента.

Один из вариантов - запустить пользовательский метод проверки, но вам может потребоваться добавить некоторые поля в модель.Вот пример - я предполагаю, что ваша Модель называется article

Class Article < ActiveRecord::Base
  validate :ready_to_publish

  def publish
    self.published = true
    //and anything else you need to do in order to mark an article as published
  end

  private
  def ready_to_publish
    if( published? ) 
      //checks that all fields are set 
      errors.add(:description, "enter a description") if self.description.blank?
    end
  end
end

. В этом примере клиентский код должен вызывать an_article.publish, а когда вызывается article.save, он сделает все остальное автоматически.Другое большое преимущество этого подхода заключается в том, что ваша модель всегда будет согласованной, а не в зависимости от того, какое действие было вызвано.

1 голос
/ 18 февраля 2011

Если ваше действие «опубликовать» устанавливает какое-либо поле статуса на «опубликовано», вы можете сделать:

validates_presence_of :description, :if => Proc.new { |a| a.state == 'published' }

или, если у каждого состояния есть свой собственный метод

validates_presence_of :description, :if => Proc.new { |a| a.published? }
...