2014-09-05 3 views
0

У меня есть два связанных классов, как это:Предотвратить родительский объект для сохранения при сохранении объекта ребенок не

class Purchase < ActiveRecord::Base 
    has_many :actions 

    before_create do |p| 
    self.actions.build 
    end 
end 

class Action < ActiveRecord::Base 
    belongs_to :purchase 

    before_save do |a| 
    false 
    end 
end 

блок в Action классе предотвращает его сохранения. Я думал, что Purchase.create потерпит неудачу, потому что он не может сохранить дочерний объект. Но пока он не сохраняет Action, он фиксирует Purchase. Как я могу предотвратить сохранение родительского объекта при наличии ошибки в дочернем объекте?

+0

http://apidock.com/rails/ActiveRecord/Validations/ClassMethods/validates_associated –

+0

Спасибо, но это ничего не изменило. – lunr

ответ

0

Оказывается, вам нужно откатить транзакцию явно, ошибки от дочерних объектов не распространяются. Так я закончил с:

class Purchase < ActiveRecord::Base 
    has_many :actions 

    after_create do |p| 
    a = Action.new(purchase: p) 
    if !a.save 
     raise ActiveRecord::Rollback 
    end 
    end 
end 

class Action < ActiveRecord::Base 
    belongs_to :purchase 

    before_save do |a| 
    false 
    end 
end 

принять к сведению, что я также изменил before_create обратный вызов after_create. В противном случае, так как belongs_to также приводит к родителю быть сохранен, вы получите SystemStackError: stack level too deep.

0

Попробуйте использовать этот код в Purchase классе:

validate :all_children_are_valid 
def all_children_are_valid 
    self.actions.each do |action| 
    unless action.valid? 
     self.errors.add(:actions, "aren't valid") 
     break 
    end 
    end 
end 

Или использовать validates_associated в Purchase классе:

validates_associated :actions 
0

Если в вашей бизнес-логики, вы не можете сохранить покупки без каких-либо действий, то добавить валидатор присутствия на действия внутри закупок

validates :actions, length: {minimum: 1}, presence: true 
Смежные вопросы