#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. должен ли я проверять в каком-то месте ошибки, которые я добавляю, или он будет проверять автоматически и генерировать уведомление?