Как (заменить | создать) поле перечисления на маршрутах рельсов 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 %>