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