Ответ 1
Обновление: см. ответ майка Слэйта для более быстрого решения: fooobar.com/questions/275397/....
Я столкнулся с той же проблемой, и вот что я сделал, чтобы выяснить, что происходит...
(TL; DR: полный список кодов приведен внизу.)
Во-первых, для класса объекта, который я пытаюсь уничтожить, я запустил его, чтобы выяснить, какие все ассоциации установлены как dependent: :destroy
:
ary =
<MyClass>.reflect_on_all_associations.select { |a|
a.options[:dependent] == :destroy
}.map(&:name)
Затем я вызвал каждую из ассоциаций, названных в ary
, на свой объект и собрал результаты. Это ограничивает имена ассоциаций только теми, которые на самом деле имеют зависимые объекты:
ary.select! { |association_name|
<my_object>.send(association_name).present?
}
Затем я могу попытаться уничтожить каждый из объектов, возвращаемых этими именами ассоциаций, чтобы найти проблемный объект (ы):
associated_objects =
ary.each_with_object([]) { |association_name, acc|
acc.concat(<my_object>.send(association_name))
}
problem_objects =
associated_objects.select { |obj| obj.destroy; obj.errors.any? }
# ...
Затем я могу посмотреть на ошибки в каждом проблемном объекте:
problem_objects.map(&:errors)
И именно там я наконец-то увидел ошибку, из-за которой уничтожение не удалось. Оттуда это было Простое Дело Программирования (SMOP), чтобы исправить проблему.
В моем случае был обратный вызов before_destroy
, не позволяющий разрушению работать с одной из моих зависимых объектных ассоциаций. Чтобы упростить отладку в будущем, я решил начать регистрировать ошибку в журнале Rails при неудачных обратных вызовах (в дополнение к добавлению сообщения об ошибке в errors.base
).
Полный список кодов:
my_object = <your_object_here>
ary =
my_object.class.reflect_on_all_associations.select { |a|
a.options[:dependent] == :destroy
}.map(&:name)
ary.select! { |association_name| my_object.send(association_name).present? }
associated_objects =
ary.flat_map { |association_name| my_object.send(association_name) }
problem_objects =
associated_objects.select { |obj| obj.destroy; obj.errors.any? }
problem_objects.map(&:errors)