Подтвердите модель для определенного действия - PullRequest
3 голосов
/ 26 ноября 2010

Мне нужно проверить модель только для определенного действия (: создать).Я знаю, что это плохая тактика, но мне просто нужно сделать это в моем случае.

Я пытался использовать что-то вроде:

validate :check_gold, :if => :create

или

validate :check_gold, :on => :create

Но я получаю ошибки.Проблема в том, что я не могу выполнить свою пользовательскую проверку check_gold при редактировании, а только при создании (поскольку проверка золота должна выполняться, только когда альянс создан, а не отредактирован).

Спасибо за чтение:)


Я добавляю некоторый фактический код:

  attr_accessor :required_gold, :has_alliance
  validate :check_gold
  validate :check_has_alliance

Это модель Альянса.: required_gold и: has_alliance оба установлены в контроллере (они являются виртуальными атрибутами, потому что мне нужна информация от контроллера).Теперь фактические валидаторы:

  def check_gold
    self.errors.add(:you_need, "100 gold to create your alliance!") if required_gold < GOLD_NEEDED_TO_CREATE_ALLIANCE
  end

  def check_has_alliance
    self.errors.add(:you_already, "have an alliance and you cannot create another one !") if has_alliance == true
  end

Это прекрасно работает для создания, но я хочу ограничить его только созданием, а не редактированием или другими действиями скаффолда.

Ответы [ 3 ]

8 голосов
/ 26 ноября 2010

Все ActiveRecord валидаторы имеют опцию :on.

validates_numericality_of :value, :on => :create 

Используйте обратный вызов validate_on_create вместо validate:

validate_on_create :check_gold
validate_on_create :check_has_alliance

Edit:

Если вы используете validates_each, вы можете использовать стандартные опции, доступные для декларации валидатора.

validates_each :required_gold, :has_alliance, :on => :create do |r, attr, value|
  r.check_gold if attr == :required_gold
  r.check_has_alliance if attr == :has_alliance
end
0 голосов
/ 26 ноября 2010

Как сказал Сэм, вам нужен before_create обратный вызов.Обратные вызовы в основном означают «выполнять этот метод всякий раз, когда запускается это действие».(Подробнее об обратных вызовах здесь: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html).

Это то, что вы хотите в своей модели:

before_create :check_gold

# other methods go here

private # validations don't need to be called outside the model

def check_gold
  # do your validation magic here
end

Вышеупомянутый метод является самым простым, чтобы делать то, что вы хотите, но к вашему сведению, есть такжеспособ использования обратного вызова before_save для выполнения дополнительных действий при создании:

before_save :check_gold_levels

# other methods

private
def check_gold_levels
  initialize_gold_level if new? # this will be done only on creation (i.e. if this model's instance hasn't been persisted in the database yet)
  verify_gold_level # this happens on every save
end

Для получения дополнительной информации о 'new?' см. http://api.rubyonrails.org/classes/ActiveResource/Base.html#method-i-new%3F

0 голосов
/ 26 ноября 2010

Вам нужно изучить обратные вызовы.Кто-то однажды сказал мне это, и я не понял, что они имели в виду.Просто выполните поиск обратных вызовов rails, и вы получите изображение.

В вашей модели вам необходимо выполнить обратный вызов.Требуется обратный вызов before_create, а затем перед созданием объекта вы сможете выполнить некоторую логику для проверки ошибок.

model.rb

before_create :check_gold_validation

def check_gold_validation
    validate :check_gold
end 

def check_gold
   errors.add_to_base "Some Error" if self.some_condition?
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...