28


29

私が行っているマイグレーションの中でenumフィールドを作成したいのですが、Googleで検索してみましたが、マイグレーションでそれを実行する方法が見つかりません

私が見つけた唯一のものは

t.column:status、:enum、:limit => [:受け入れられた、:取り消された、:保留中]

しかし上記のコードはrails 1.xxxでしか動かず、私はrails 2.0を動かしているようです。

これは私が試したが失敗する

クラスCreatePayments <ActiveRecord :: Migration def self.up create_table:payment do | t | t.string:concept t.integer:user_id t.text:メモt.enum:status、:limit => [:受け入れられました、:取り消されました、:保留中]

t.timestampsの終わりと終わり

def self.down drop_table:支払い終了

それで、それが許されない場合、あなたは何が良い解決策であると思いますか? 単なるテキストフィールドであり、モデルから検証しますか?

10 Answer


36


代わりに `+ t.column +`メソッドを使用して、手動でタイプを指定できます。 Railsはこれを文字列カラムとして解釈します、そしてPavelが提案したように単にバリデータをモデルに追加することができます:

class CreatePayments < ActiveRecord::Migration
  def self.up
    create_table :payments do |t|
      t.string :concept
      t.integer :user_id
      t.text :notes
      t.column :status, "ENUM('accepted', 'cancelled', 'pending')"

      t.timestamps
    end
  end

  def self.down
    drop_table :payments
  end
end

class Payment < ActiveRecord::Base
  validates_inclusion_of :status, :in => %w(accepted cancelled pending)
end


24


これこそまさにあなたが必要としているものです。

クラスUser <ActiveRecord :: Base validates_inclusion_of:status、:in => [:active、:inactive]

def status read_attribute(:status).to_sym end

def status =(値)write_attribute(:status、value.to_s)end end

HTH


9


あなたは(非常に)包括的なjeffのhttp://github.com/jeffp/enumerated_attribute[enumerated_attribute gem]を試すか、またはこの簡単な回避策を試してみてください。

class Person < ActiveRecord::Base
  SEX = [:male, :female]

  def sex
    SEX[read_attribute(:sex)]
  end

  def sex=(value)
    write_attribute(:sex, SEX.index(value))
  end
end

そして、 `+ sex +`属性を整数として宣言します:

t.integer :sex

これは私にとってとてもうまくいった! =D


4


私はこれらの小さなenumをたくさん持っていて、それぞれに3-300のエントリがあります。 私はそれらをルックアップテーブルとして実装します。 それぞれにモデルファイルはありません。各テーブルには同じ列のセット(id、name、description)があるため、メタプログラミングを使用してそれぞれのモデルを生成します。

いくつかのセットはそれら自身のテーブルを保証するのに十分な要素を持っていたので、それらをすべてテーブルに移動することはより一貫していました。 これらの列挙型を後で追加する場合は、別の選択肢があります。

*編集:*モデルを生成する方法は次のとおりです。

ACTIVE_RECORD_ENUMS = %w{
  AccountState
  ClientType
  Country
  # ...
}

ACTIVE_RECORD_ENUMS.each do |klass|
  eval "class #{klass} < ActiveRecord::Base; end"
  klass.constantize.class_eval do
    class << self

      def id_for(name)
        ids[name.to_s.strip.humanize.downcase]
      end

      def value_for(id)
        values[id.to_i]
      end

      def values
        @values ||= find(:all).inject({}) {|h,m| h[m.send(primary_key)] = m.name; h}
      end

      def ids
        @ids ||= self.values.inject({}) {|h, {k, v}| h[v.downcase] = k; h}
      end

    end
  end
end

このファイルはモデルディレクトリにあり、 `+ application_config.rb +`に含まれています。 これは私がこのようなことをすることができます:

AccountState.ids
# => {"active" => 1, "deleted" => 2}
AccountState.values
# => {1 => "Active", 2 => "Deleted"}
AccountState.id_for("Active")
# => 1
AccountState.value_for(1)
# => "active"


3


RubyForgeの enum-columnプラグインを見ましたか?


3


同様に、_enumerated_attribute_gemはオブジェクトレベルで列挙型を管理します。

enum_attr:状態、%w(キャンセルされた承認済み^保留中)

移行で文字列を定義する

t.string:ステータス

動的述語メソッドのような優れた機能も提供します。


2


以下を追加してください。

module ActiveRecordモジュールConnectionAdapters#:nodoc:class TableDefinition定義列挙(* args)options = args.extract_options! column_names = args

column_names.each {| name | column(name、 'enum'、options)}エンドエンドエンドエンドエンド

lib / enum / table_definition.rbに追加してinit.rbに含めます。


0


[OK]を、レール全体のAPIを読んで、私が必要としているものを見つけ、私は好きではない :( Rails doesn’t support emum as native type on migrations, ここの情報です。プラグインまたはその他の方法を検索する必要があります。

私はあなたが投稿し続けます。


0


もう一つの選択肢:SQLへのドロップ。

def self.up "ALTER TABLE` payment` ADD `status` ENUM( '承認'、 'キャンセル'、 '保留')の実行


0


simple_formではこれを使います。

<%= f。入力:性別、:コレクション=> {'男性' => '男性'、 '女性' => '女性'}、:include_blank => false%>