2010-04-11 19 views
15

Me pregunto cómo podría crear un tipo de datos personalizado para usar dentro del archivo de migración de rake. Ejemplo: si está creando un modelo, dentro del archivo de migración puede agregar columnas. Se podría tener este aspecto:Rieles: creación de un tipo de datos personalizado/creación de una abreviatura

def self.up 
    create_table :products do |t| 
     t.column :name, :string 
     t.timestamps 
    end 
    end 

me gustaría saber cómo crear algo como esto:

t.column :name, :my_custom_data_type 

La razón de esto para crear, por ejemplo, un tipo de "moneda", que no es otra cosa que un decimal con una precisión de 8 y una escala de 2. Como uso solo MySQL, la solución para esta base de datos es suficiente.

¡Gracias por sus comentarios y comentarios!

+0

Usar tipos de datos de coma flotante para moneda es generalmente una idea terrible. –

+0

Si tiene una mejor solución, por favor elabore. – Shyam

+1

Usa algo como la gema del dinero, http://money.rubyforge.org/. – theIV

Respuesta

21

Lo que quiere hacer es definir un nuevo método de creación de columna que proporcione las opciones para crear su tipo personalizado. Lo cual se hace esencialmente agregando un método que se comporta como t.integer ... en migraciones. El truco es averiguar dónde agregar ese código.

Algunos donde en su lugar inicializadores directorio de este fragmento de código:

module ActiveRecord::ConnectionAdapters 
    class TableDefinition 
    def currency (*args) 
     options = args.extract_options! 
     column_names = args 
     options[:precision] ||= 8 
     options[:scale] ||= 2 
     column_names.each { |name| column(name, 'decimal', options) } 
    end                  
    end 
end 

Ahora se puede utilizar el método de la moneda hacen definir una columna de divisas en cualquier momento que lo necesite.

Ejemplo:

def self.up 
    create_table :products do |t| 
    t.currency :cost 
    t.timestamps 
    end 
end 

Para agregar una columna de divisas a una tabla existente:

def self.up 
    change_table :products do |t| 
    t.currency :sell_price 
    end 
end 

Advertencia: que no tiene tiempo para probarlo, así que no hay garantías. Si no funciona, al menos debería ponerlo en el camino correcto.

+0

Voy a probar esto de inmediato. ¡Gracias por el esfuerzo y tu ayuda! – Shyam

+0

Gracias, solo tenía un uso para eso. Una cosa a tener en cuenta: 't' es una' TableDefinition' en 'create_table', pero una' Table' en 'change_table'. Puse mi código de generación personalizado en un módulo e incluí eso en ambas clases. – Kolja

+0

Hola, @emfi Esto es realmente bueno. ¿Hay alguna forma de llevarlo más lejos, como tener una moneda modelo? Solo un pensamiento porque quiero, por ejemplo, para validaciones de entrada de moneda en el mismo lugar también ... También buscaré eso ... gracias – sethi

Cuestiones relacionadas