Классы Ruby - это просто объекты, поэтому сравнение основано на идентичности объекта (т. Е. Тот же указатель под капотом).
Не уверен, что происходит в вашем случае, но я постараюсь отладить в нескольких местах и посмотреть, какие идентификаторы объектов и предков вы получите для MysqlError. Я подозреваю, что есть два таких объекта в разных модулях, и ваше предложение catch ссылается на неправильный.
Edit:
Это довольно странно. Теперь я предполагаю, что MysqlError или один из его предков был включен в две разные точки в цепочке классов ваших контроллеров, и это как-то запускает перехват исключений.
Теория # 2 состояла бы в том, что, поскольку rails переопределяет const_missing для выполнения автоматических требований, в котором вы ожидаете получить исключение UndefinedConstant в предложениях обработки исключений, вместо этого нужно найти что-то под этим именем, которое бог знает где в дереве исходников. Вы сможете увидеть, так ли это, протестировав с автоматическим отключением (т. Е. Выполнить несколько отладок в режиме dev и prod).
Существует синтаксис, заставляющий вашу ссылку начинаться с корня, которая может быть полезна, если вы можете найти правильный, на который ссылаетесь:
::Foo::Bar
Рант:
В таких вещах, как мне кажется, есть некоторые недостатки рубинового шоу. Под капотом объектной модели и области видимости Ruby находятся все объектные структуры, указывающие друг на друга, таким образом, что это очень похоже на javascript или другие языки на основе прототипов. Но это проявляется непоследовательно в синтаксисе класса / модуля, который вы используете в языке. Кажется, что с помощью некоторого тщательного рефакторинга вы могли бы сделать это более понятным, а также упростить язык, хотя это, конечно, было бы крайне несовместимо с существующим кодом.
Совет:
Когда вы используете для отладки put, попробуйте делать так, чтобы положить foo.inspect, так как он будет отображаться так, как вы привыкли с irb.