2011-04-14 15 views
7

Tengo un problema de diseño que quiero revisar.Campos dinámicos con Rails 3

Estoy construyendo una aplicación Rails 3 que contendrá productos de una variedad de compañías diferentes. Me gustaría definir un gran conjunto de campos y cada producto puede seleccionar los campos que se le aplican.

Los tipos de campo serán campos de texto de una sola línea, campos de texto de varias líneas, opciones de radio o selección, opciones de casillas de verificación, fechas, duraciones o algo más personalizado. Necesitaré poder representar dinámicamente los campos basados ​​en este tipo para editar y mostrar.

Mi idea actual es usar MongoDB y almacenar todo en un hash en el producto.

class Product 
    include Mongoid::Document 
    def self.field_definitions 
    [{ :name => :code, :label => 'Code' }, 
    { :name => :itinerary, :type => :multiline, :label => 'Itinerary', :category => :tour}, 
    { :name => :infant_age, :type => :age_range, :label => 'Infante age range', :category => :tour}, 
     ... 
    ] 
    end 

    embedded_in :company 
    field :field_data, type:Hash 
end 

A continuación, hacer que los campos para la nueva/editar algo como:

= form_for Product.new do |f| 
    = f.fields_for :field_data do |f| 
    %ol 
     - Product.field_definitions.each do |field_definition| 
     %li 
      = f.label field_definition[:name], field_definition[:label] 
      = render "products/edit_fields/#{field_definition[:type] || 'singleline'}", :f => f, :field_definition => field_definition 

    = f.submit "Create" 

Entonces tengo un parcial para cada tipo de campo para editar y espectáculo.

Después de la creación, un producto puede tener un aspecto como este en mongodb:

{"field_data":{ 
    "itinerary": "FUN!", 
    "code": "AHKDYK", 
    "infant_age": { "max": 2, "min": 0 } 
}} 

Es este un buen enfoque?

Respuesta

5

Claro, eso funcionará, pero ¿sabe usted que no necesita ir a Mongo solo para poder almacenar un hash de valores en la base de datos? También puede establecer un atributo como serialize, luego Rails lo convertirá en YAML y volverá a un objeto (simple) en el camino de regreso.

Este es un enfoque bastante común (y muy viable) para el patrón que usted describe.

0

Puede definir esos campos como campos Mongoid :: Document y usar Product.fields como una introspección. A continuación, puede aprovechar las características de ActiveModel, como las validaciones, así como i18n (si es necesario).

Cuestiones relacionadas