PostgreSQL具有内置于数据库中的enumerated types的概念。如何在Rails 3的Postgres数据库中使用枚举?
你将如何实现一个列使用Rails 3中的枚举类型的列表?你需要以某种方式定义PostgreSQL中的枚举吗?你怎么能创建一个这样做的数据库迁移?
在Rails 3.07,Ruby 1.92p180,PostgreSQL 8.3中工作。
PostgreSQL具有内置于数据库中的enumerated types的概念。如何在Rails 3的Postgres数据库中使用枚举?
你将如何实现一个列使用Rails 3中的枚举类型的列表?你需要以某种方式定义PostgreSQL中的枚举吗?你怎么能创建一个这样做的数据库迁移?
在Rails 3.07,Ruby 1.92p180,PostgreSQL 8.3中工作。
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迁移。)
您还可以设置使用的模式原始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 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
什么EXAC tly可以防止你通过迁移在Postgresql中添加这个枚举,并在之后使用它? – plang