Перед действием сохранения и проверкой

#ruby-on-rails #ruby-on-rails-4

#ruby-on-rails #ruby-on-rails-4

Вопрос:

В моем приложении есть логика: родительская модель перед сохранением генерирует элементы дочерней модели.

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

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

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

Ответ №1:

Поправьте меня, если я неправильно понял вашу проблему, но вы хотите проверить, имеет ли родительская модель хотя бы 1 дочерний элемент, прежде чем родительская модель запустит обратный вызов ‘before_save’ (который будет делать все, что захочет), верно?

Если да, вы можете использовать обратный вызов ‘before_validation’. ‘before_validation’ вызывается перед ‘before_save’. Итак, вы можете сделать что-то вроде:

 before_validation { self.errors.add(:base, 'error here or something') if self.children.count < 1 }
  

Обратите внимание, что rails даже не будет пытаться сохранить ресурс, если массив ошибок ресурса не пуст (поэтому обратный вызов before_save вызываться не будет). выполнение ‘self.errors.add’ в обратном вызове ‘before_save’ не остановит сохранение ресурса. Если вы хотите остановить сохранение ресурса из обратного вызова ‘before_save’, вы можете сделать:

 before_save do 
  self.errors.add(:base, 'error here or something')
  false
end
  

Надеюсь, это помогло. 🙂

Приветствия!

Комментарии:

1. спасибо за ответ. Нет, наоборот — я генерирую дочерние элементы в before_save обратном вызове при анализе данных файла, и я хочу проверить после того, как я проанализирую файл, у этого родительского элемента есть хотя бы один элемент, иначе это означает, что формат файла был неправильным.

2. В этом случае вы просто выполняете синтаксический анализ и проверку внутри before_save и просто убедитесь, что вы делаете ошибки.добавьте и верните false, если формат неверен. 🙂 Рад, что могу помочь.

Ответ №2:

Что-то вроде этого:

 class Hero < ActiveRecord::Base
  has_many :weapons

  before_save :check_equipment

  private
    def check_equipment
      errors.add(:weapons, "are not equipped") if weapons.size < 1 
    end
end

class Weapon < ActiveRecord::Base
  belongs_to :hero
end
  

Вы можете создать оружие как независимый объект, а затем связать оружие с героями, или вы также можете создать оружие с помощью метода hero just use accepts_nested_attributes_for . Решение зависит от вашей архитектуры приложения.

Комментарии:

1. я не уверен, но validates :weapons, presence: true тоже может работать

2. Где я должен генерировать оружие?

3. Извините, я не понял. before_save :parse_file Итак, в моей родительской модели я должен добавить второй метод перед сохранением или перемещением:parse_file в другое место?

4. Попробуйте перед _save :parse_file, :check_weapon

5. должен ли я проверять в каком-то месте ошибки, которые я добавляю, или он будет проверять автоматически и генерировать уведомление?