Як я можу дізнатись у рейках, що спричинило помилку .save (), крім помилок перевірки?


91

У мене є модель ActiveRecord, яка повертається trueз valid?(а .errors порожня), але повертається falseз save(). Якщо екземпляр моделі є дійсним, як я можу дізнатися, що спричиняє помилку збереження?


7
У мене була ця проблема пару тижнів тому. Деякий рефакторинг залишив функцію before_save, яка постійно повертає значення false, що призводить до помилки збереження.
Джефф Пакет

1
@Jeff - дякую, виявляється, був метод: before_save, який повертав false. Як ти це дізнався? Це була просто перевірка коду?
kdt

Це була перевірка коду, і розбіжності проти контролю версій.
Джефф Пакет

Відповіді:


48

Перевірте всі свої зворотні дзвінки.

У мене була така проблема, як у мене, і метод "after_validate", який виявився невдалим після того, як я вніс купу змін до моделі. Модель була дійсною, але функція "after_validate" повертала false, тому, якщо я використовував model.validїї, сказав true, але якщо я її зберігав, це дало мені помилки перевірки (передані через зворотний виклик after_validate). Це було дивно.

Подивіться на трасування програми, і ви зможете побачити, який рядок коду викликає виняток.


2
Відповідно до коментаря Джеффа, виявилося, що зворотний виклик before_save повертає false.
kdt

3
@kdt - саме в цьому була моя проблема. Я не думав про це, тому що before_save просто призначений для встановлення властивості, а оскільки він встановлював для нього значення false, яке неявно поверталось і що змусило зберегти мовчки. З позитивного боку, тепер у мене є можливість виправити цей код, додавши рядок "Hey! That's MY fake leg!" # Believe it or not, this is important. Не те щоб я це зробив. ;)
Натан Лонг

2
Хорошим способом забезпечити справжнє повернення вартості єtrue.tap { do_something }
Натан Лонг

вау, яка незрозуміла проблема. Ніколи не здогадався б, що зворотний виклик, що повертає значення false, перестав би зберігатись. Хтось може підказати мені документи щодо цього? Дякуємо, що вказали на це!
andy


116

Спробуйте використати версію bang save!(зі знаком оклику в кінці) та перевірити отриману помилку.


4
економити! просто кидає RecordNotSaved (коли я друкую .message винятку, я просто отримую ім'я класу винятку). Я десь мав би шукати більше деталей?
kdt

1
Якщо ви перебуваєте в режимі розробки Rails, він повинен надрукувати повний опис помилки із трасуванням стека. Подивіться там на будь-які підказки та / або опублікуйте їх тут.
Andy Lindeman

1
Я використовую консоль, завантажую об'єкт (наприклад, o = Object.find #id), а потім виконую o.save! як відповідає відповідь. Він друкує, чому це не економить.
пдюей

1
FYI, дзвінок save!може підвищити ActiveRecord::RecordInvalid(оскільки він запускає перевірку), або приблизно ActiveRecord::RecordNotSavedтак ви захочете врятувати.
Денніс

2
+1, оскільки це найменш незадовільна відповідь на фундаментальне питання про те, як діагностувати .saveзбої, які не пов’язані з валідацією. Кваліфікація "найменш незадовільна" стосується Rails, а не цієї відповіді.
Чак Батсон,

111

Якщо @user.save(наприклад) повертається false, просто запустіть це, щоб отримати всі помилки:

@user.errors.full_messages

13
Як я вже згадував у питанні, .valid? правда - тобто помилок перевірки немає. Я перевірив, що .errors також повертає порожній список (я оновив запитання, щоб вказати на це)
kdt

3

Так, я вирішив цю проблему, переконавшись, що я повернув true у всіх своїх зворотних викликах before_ *, після чого він почне працювати :)


-1

Проблема у мене полягала в тому, що я забув додати перевірку до моделі.

class ContactGroup < ActiveRecord::Base
  validates_presence_of :name
end
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.