Исключения следует использовать для исключительных ситуаций, ваша ситуация не является исключительной.Для рельсов 4 вы должны вернуть false, а для рельсов 5 вы должны вызвать throw(:abort)
, чтобы предотвратить уничтожение записи.
Вы можете добавить ошибку (чтобы получить некоторую обратную связь), а затем отменить, если условие истинно:
before_destroy :destroyable?
def destroyable?
return true if phase.companies.count == 0
errors.add(:companies, 'is not empty')
throw(:abort)
end
Теперь вы можете проверить это следующим образом:
checklist.destroy
expect(checklist).not_to be_destroyed
expect(checklist.errors[:companies]).to eq 'is not empty'
Проверьте DOC обратных вызовов, раздел «Отмена обратных вызовов» https://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
РЕДАКТИРОВАТЬ: Если вывсе еще хотите иметь исключение, когда запись не уничтожена, тогда обратный вызов before_destroy будет таким же, но вместо этого вы вызываете destroy!
(обратите внимание на «!»), что вызывает исключение ActiveRecord::RecordNotDestroyed
.
Противоинтуитивно выдвигать исключение как destroy
отмена, так как это не должно работать по соглашению.