Я создаю свое первое приложение на Rails и сталкиваюсь с этой странной проблемой. Я использую Postgres, который поддерживает очень полезный для меня тип ENUM. Однако Rails не поддерживает это, поэтому я использую много «выполнений» в своих миграциях. Все они работают успешно и, кажется, работают. Моя база данных - именно та, которую я хочу, когда проверяю ее через pgAdmin. На данный момент я использую 3 типа ENUM в таблице users
:
gender ('female', 'male')
interested_in ('men', 'women', 'men_and_women')
relationship_status ('single', ..., 'divorced')
Со стороны приложения я использую гем classy_enum. Затем я попытался обновить профиль пользователя, чтобы проверить, все ли работает. Сначала я удалил interested_in
из формы редактирования профиля, потому что в нем была другая логика. Все нормально работало. Затем я добавил interested_in
, обновил логику для нового типа и снова отправил форму. У меня такая ошибка:
PG::InvalidTextRepresentation: ERROR: invalid input value for enum interested_in: "0" :
UPDATE "users" SET "interested_in" = $1, "remember_token" = $2, "updated_at" = $3 WHERE "users"."id" = 1
Он пытается сохранить 0 в поле перечисления, которое не включает эту опцию, а затем явно терпит неудачу. Итак, когда я впервые увидел подобную ошибку, я подумал «откуда, черт возьми, этот 0?» но оказалось, что Rails конвертирует значение в целое число перед его сохранением, и всякий раз, когда вы конвертируете строку с нечисловыми символами, результатом будет 0. Я полагаю, что это происходит снова. Я подошел к консоли и набрал:
2.0.0p247 :001 > User.columns_hash['interested_in'].type
=> :integer
Когда я запускаю ту же команду для gender
и relationship_status
, я получаю nil, что имеет смысл, потому что Rails не понимает тип ENUM:
2.0.0p247 :007 > User.columns_hash['gender'].type
=> nil
В pgAdmin у меня есть:
а также
соответственно.
Я попытался перезапустить свой веб-сервер (Pow), сервер postgres, но типы по-прежнему не совпадают. Как это может быть возможным? Как работают адаптеры базы данных Rails? Что я могу сделать, чтобы разрешить эту запутанную ситуацию?