ruby-on-rails - remove - rollback migration rails
¿Cómo(reemplazar | crear) un campo enum en migraciones Rails 2.0? (10)
¿Has visto el complemento de enum-column en RubyForge?
Me gustaría crear un campo de enumeración en la migración sone que estoy haciendo. Intenté buscar en Google pero no puedo encontrar la manera de hacerlo en la migración.
Lo único que encontré fue
t.column :status, :enum, :limit => [:accepted, :cancelled, :pending]
pero parece que el código anterior solo se ejecuta en los rieles 1.xxx y ya estoy corriendo los rieles 2.0
esto lo intenté pero falla
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
Entonces, en caso de que no esté permitido, ¿qué crees que podría ser una buena solución? ¿Solo un campo de texto, y validación desde el modelo?
Agregue lo siguiente:
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
a lib / enum / table_definition.rb e inclúyalo en su init.rb.
Con simple_form utilizo esto:
<%= f.input :gender, :collection => {''Male'' => ''male'',''Female'' => ''female''}, :include_blank => false %>
De manera similar, la gema enumerated_attribute administra las enumeraciones en el nivel de objeto.
enum_attr :status, %w(accepted cancelled ^pending)
Definir una cadena en la migración.
t.string :status
También proporciona algunas características interesantes como métodos de predicado dinámico.
Mire la punta # 3 en http://zargony.com/2008/04/28/five-tips-for-developing-rails-applications
Esto es exactamente lo que necesitas!
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
HTH
Otra opción: soltar a SQL.
def self.up
execute "ALTER TABLE `payments` ADD `status` ENUM(''accepted'', ''cancelled'', ''pending'')"
end
Puede especificar manualmente el tipo utilizando el método t.column
lugar. Rails interpretará esto como una columna de cadena, y simplemente puede agregar un validador al modelo, como Pavel sugirió:
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
Puede probar la (muy) completa gema enumerated_attribute de jeff O vaya con esta sencilla solución:
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
Y luego declara el atributo de sex
como un número entero:
t.integer :sex
Esto funcionó muy bien para mí! = D
Tengo docenas de estas pequeñas enumeraciones, con 3-300 entradas en cada una. Los implemento como tablas de búsqueda. No tengo un archivo modelo para cada uno; Uso algo de metaprogramación para generar un modelo para cada uno, ya que cada tabla tiene el mismo conjunto de columnas (id, nombre, descripción).
Dado que algunos de los conjuntos tenían elementos suficientes para garantizar su propia tabla, fue más consistente moverlos todos a las tablas. Solo otra opción si tendrás más de estas enumeraciones más adelante.
EDITAR: Así es como genero los modelos:
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
Este archivo se encuentra en el directorio de modelos y se incluye en application_config.rb
. Esto me permite hacer cosas como esta:
AccountState.ids
# => {"active" => 1, "deleted" => 2}
AccountState.values
# => {1 => "Active", 2 => "Deleted"}
AccountState.id_for("Active")
# => 1
AccountState.value_for(1)
# => "active"
ok, solo lea la api completa de Rails y encontré lo que necesito y no me gusta :( Rails no admite emum como tipo nativo en migraciones, here está la información, necesito buscar un complemento u otro método.
Te mantendré informado.