我正在构建我的第一个Rails应用程序,我遇到了这个奇怪的问题。我正在使用Postgres,它支持对我来说非常有用的ENUM类型。但是,Rails不支持这一点,因此我在迁移中使用了很多“执行”。他们都成功运行,似乎工作。当我通过pgAdmin检查它时,我的数据库就是我想要的方式。我目前在users
表中使用了3种ENUM类型:
gender ('female', 'male')
interested_in ('men', 'women', 'men_and_women')
relationship_status ('single', ..., 'divorced')
对于应用程序方面,我正在使用classy_enum gem。然后我尝试更新用户配置文件以检查一切是否正常。起初我从编辑配置文件表单中删除了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数据库适配器如何工作?我该怎么做才能解决这种混乱局面?
答案 0 :(得分:2)
好吧,我正在回答我自己的问题,但我还是不接受,因为我仍然希望有经验的人能够解决这个问题。
我有一种预感,它与名称interested_in
有关,以“int”开头。然后我将名称改为is_interested_in
,但没有运气,所以我放弃了这个假设。在花了几个小时困惑的问题后,放弃我的整个数据库,再次迁移,再次删除,从structure.sql加载它都没有成功,我决定再次给它一个镜头,并将类型的名称更改为{{ 1}}(因为它甚至不以“i”开头)。再一次,没有运气。由于我在网上找不到任何内容或提出任何其他假设,我花了更多的时间,我仔细检查了其他枚举类型的名称,发现它们在字符串的任何位置都没有包含“int” 。然后我将类型名称从user_interested_in
更改为interested_in
并猜猜是什么?它奏效了。
attracted_to
我的猜测是Rails中存在一个错误。似乎它试图变得聪明并且用一些逻辑来猜测列类型:
User.columns_hash['interested_in'].type
=> nil
但那有点疯狂。为什么不检查完整匹配?对我没有任何意义。
修改强>
嗯,就是这样。刚刚检查了Rails source,这正是它的作用:
model_column_type = :integer if db_column_type.include?("int")
对于支持类型创建的数据库来说,这是一个严重的问题。正则表达式真的必须如此具有包容性吗?让我想知道我是否应该创建一个问题。
答案 1 :(得分:0)
查看以下Github存储库链接:here。我不确定它下面发布了什么许可证,因此在提及实施思路时要小心。