20

PostgreSQLにはenumerated typesのコンセプトがデータベースに組み込まれています。Rails 3のPostgresデータベースでenumを使用するには?

Rails 3で列挙型を使用する列を持つ表を実装するにはどうすればよいですか?あなたは何とかPostgreSQLでenumを定義する必要がありますか?これを行うDB移行をどのように作成できますか?

Working in Rails 3.07、Ruby 1.92p180、PostgreSQL 8.3。

+0

何exac:あなたのタイプに、たとえば

scope :my_enum_value_is, ->(value){ where('my_enum_value = ?::my_enum_type', value) } 

のためにあなたはまた、列パーサにパッチを適用したいと思いますPostgreSQLでこの列挙型をマイグレーションによって追加したり、後でそれを使用したりするのを防ぎますか? – plang

答えて

13

レールは、ENUMのデータ型をサポートしていません。これは、すべてのデータベースがそのデータ型をサポートしているわけではないためです。 ENUMの値を扱う一般的な方法は、データベース(あなたの場合はPostgreSQL)に列挙型列を手動で作成し、それをRailsアプリケーションのstring列として扱うことです。次に、validates_inclusion_ofバリデータを使用して、許可された値の使用を強制します。

validates_inclusion_of :gender, :in => [ "male", "female" ] 

そして、enumフィールドを追加するには、移行のネイティブ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 enumsvalidates_inclusion_ofは今に変更することができます:

enum gender: [ :male, :female ] 

(ただし、これはまだネイティブ基礎となるデータベースでサポートされていないので、ネイティブSQLの移行がまだ必要とされている。)

+3

これは、shema.rbが破損しているため、スキーマを実行できないことを意味します。 mysqlには、rubygem-enum_column3 gemがあります。ポストグルクのために働くようにそれを修正するのはどれほど難しいのだろう。 – yxhuvud

+0

その情報をありがとう。 'ENUM'や' schema:load'を使用することはほとんどありません) – rdvdijk

+0

あなたはテストをしていませんか?それはスキーマを使用する:負荷。テストデータベースの列挙型は、代わりに文字列として終了します。 – yxhuvud

9

また、使用するスキーマを設定することができます.rbファイルの代わりに未処理のSQLを使用します。単純に汎用データストアとして使用するのではなく、データベースのより高度な機能(列挙型、全文検索、トリガ、関数など)を活用している場合、これはあなたの人生を楽にします。

はちょうどあなたの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

、(そしておそらく3.2)を使用すると、「無効なOID」タイプの警告を避けるために、この操作を行うことができます。

ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID.alias_type 'my_enum_type', 'text' 

照会、あなたはまた、文字列を変換することになるでしょう

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 
+1

非常に興味深い。さらに、ActiveRecordが ':: my_enum'キャストを特定の定数に自動的に追加する方法があるのはすばらしいことです。 – rewritten

+0

@rewrittenレールが自動的に変換されるようにすることもできます。ポイントタイプを参照してください(https://github.com/rails/rails/pull/7324)。私が助けてくれることを嬉しく思います(マスターにするためにschema.rbサポートが必要です)。 – glebm

+0

私はそれが特定の型のためだと思います。任意のユーザー定義型または列挙型を管理するコードをいくつか用意していますか?ツイッターでこれを続けて、ちょうどあなたに続きました... – rewritten

関連する問題