如何在 Rails 3 的 Postgres 数据库中使用枚举? [关闭]
Posted
技术标签:
【中文标题】如何在 Rails 3 的 Postgres 数据库中使用枚举? [关闭]【英文标题】:How to use enum in a Postgres database in Rails 3? [closed] 【发布时间】:2011-11-12 08:06:44 【问题描述】:PostgreSQL 在数据库中内置了enumerated types 的概念。
如何在 Rails 3 中实现一个包含使用枚举类型的列的表?您是否需要以某种方式在 PostgreSQL 中定义枚举?您如何创建执行此操作的数据库迁移?
在 Rails 3.07、Ruby 1.92p180、PostgreSQL 8.3 中工作。
【问题讨论】:
究竟是什么阻止了您通过迁移在 Postgresql 中添加此枚举,并在之后使用它? 【参考方案1】:Rails 不支持开箱即用的 ENUM
数据类型。这是因为并非所有数据库都支持该数据类型。我发现处理ENUM
值的常用方法是在数据库中手动创建枚举列(在您的情况下为PostgreSQL),并将其作为Rails 应用程序中的string
列处理。然后,使用validates_inclusion_of 验证器强制使用允许的值。
validates_inclusion_of :gender, :in => [ "male", "female" ]
并在您的迁移中使用原生 SQL 来添加枚举字段:
class AddEnumType < ActiveRecord::Migration
def up
execute ".." # your native PostgreSQL queries to add the ENUM field
end
end
编辑(2014 年 6 月)
Rails 4.1 现在supports enums。 validates_inclusion_of
现在可以更改为:
enum gender: [ :male, :female ]
(但是底层数据库仍然不原生支持,所以还是需要原生SQL迁移。)
【讨论】:
这意味着您永远无法执行 schema:load,因为它会破坏 shema.rb。对于 mysql,有 rubygem-enum_column3 gem。不知道修改它以使其也适用于 postgres 有多难.. 感谢您提供的信息。我几乎从不使用ENUM
s 或schema:load
;)
您没有任何测试?使用模式:加载。您的测试数据库枚举将改为字符串。
测试使用db:test:prepare
,它克隆了开发数据库。它不关心schema:load
。
错误。 db:test:prepare 检查挂起的迁移并从 db/schema.rb 加载架构【参考方案2】:
除了上述答案之外,对于 Rails 4(可能还有 3.2),您可以这样做以避免“无效 OID”类型的警告:
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID.alias_type 'my_enum_type', 'text'
查询时,你也会想把字符串转换成你的类型,例如
scope :my_enum_value_is, ->(value)
where('my_enum_value = ?::my_enum_type', value)
您还需要修补列解析器:
class ActiveRecord::ConnectionAdapters::Column
private
def simplified_type_with_my_enum_type(field_type)
if field_type == 'my_enum_type'
field_type.to_sym
else
simplified_type_without_my_enum_type(field_type)
end
end
alias_method_chain :simplified_type, :my_enum_type
end
【讨论】:
非常有趣。此外,如果 ActiveRecord 有一种方法可以自动将::my_enum
转换附加到特定的常量,那就太棒了。
@rewritten 可以让 Rails 自动转换它,请参阅github.com/rails/rails/pull/7324 中的点类型以供参考。如果您想向 Rails 提交 PR,我很乐意提供帮助(还需要 schema.rb 支持才能使其成为 master)。
我认为这是针对特定类型的,您是否建议使用一些代码来管理任意用户定义的类型或只是枚举?让我们继续推特,刚刚关注你...【参考方案3】:
您还可以将架构设置为使用原始 SQL 而不是 .rb 文件。如果您利用数据库的更高级功能(枚举、全文搜索、触发器、函数等)而不是简单地将其用作通用数据存储,这将使您的生活更轻松。
只需在 config/application.rb 中设置这一行
# Use SQL for the schema due to many database specific settings
config.active_record.schema_format = :sql
它会输出一个structure.sql文件,为你解决这个问题。
【讨论】:
以上是关于如何在 Rails 3 的 Postgres 数据库中使用枚举? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Postgres 数据库从一个 Elastic Beanstalk 环境复制到另一个环境?我正在使用 Rails 5
Ruby On Rails Heroku Postgres数据库SSL连接
Postgres / Rails Active Record - 查询四舍五入的浮点值