Как (заменить | создать) поле перечисления на маршрутах рельсов 2.0?

Я хотел бы создать поле enum при sone migration, которое я делаю, я пробовал искать в google, но не могу найти способ сделать это в миграции

Единственное, что я нашел, это

  t.column :status, :enum, :limit => [:accepted, :cancelled, :pending]

но выглядит как приведенный выше код работает только на rails 1.xxx, и поскольку я запускаю rails 2.0

это то, что я пробовал, но он терпит неудачу

class CreatePayments < ActiveRecord::Migration
  def self.up
    create_table :payments do |t|
      t.string :concept
      t.integer :user_id
      t.text :notes
      t.enum :status, :limit => [:accepted, :cancelled, :pending]

      t.timestamps
    end
  end

  def self.down
    drop_table :payments
  end
end

Итак, если это не разрешено, как вы думаете, может быть хорошим решением? просто текстовое поле и подтверждение из модели?

Ответ 1

Вы можете вручную указать тип с помощью метода t.column. Rails интерпретирует это как строковый столбец, и вы можете просто добавить валидатор к модели, как предложил Павел:

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

Ответ 2

Посмотрите на наконечник № 3 на http://zargony.com/2008/04/28/five-tips-for-developing-rails-applications

Это именно то, что вам нужно!

 class User < ActiveRecord::Base
   validates_inclusion_of :status, :in => [:active, :inactive]

   def status
     read_attribute(:status).to_sym
   end

   def status= (value)
     write_attribute(:status, value.to_s)
   end
 end

НТН

Ответ 3

Вы можете попробовать (очень) всеобъемлющий jeff 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

У меня есть десятки этих маленьких перечислений, по 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"

Ответ 5

Вы просмотрели плагин enum-column на RubyForge?

Ответ 6

Аналогично, enumerated_attribute gem управляет перечислениями на уровне объекта.

enum_attr :status, %w(accepted cancelled ^pending)

Определите строку в миграции

t.string :status 

Также предоставляет некоторые интересные функции, такие как динамические предикатные методы.

http://github.com/jeffp/enumerated_attribute/tree/master

Ответ 7

Добавьте следующее:

module ActiveRecord
  module ConnectionAdapters #:nodoc:
    class TableDefinition
      def enum(*args)
        options = args.extract_options!
        column_names = args

        column_names.each { |name| column(name, 'enum', options) }
      end
    end
  end
end

в lib/enum/table_definition.rb и включить его в ваш init.rb.

Ответ 8

ok, просто прочитайте все rails api и найдите то, что я сделал, и мне не нравится:( Rails не поддерживает emum как родной тип при миграции, здесь - это информация, мне нужно найти плагин или другой метод.

Я буду держать вас в курсе.

Ответ 9

Другая опция: переход к SQL.

def self.up
  execute "ALTER TABLE `payments` ADD `status` ENUM('accepted', 'cancelled', 'pending')"
end

Ответ 10

С помощью simple_form я использую это:

<%= f.input :gender, :collection => {'Male' => 'male','Female' => 'female'}, :include_blank => false %>