使用Rails 3的动态字段

时间:2011-04-14 23:47:36

标签: ruby-on-rails ruby architecture mongodb mongoid

我有一个我想要解决的设计问题。

我正在构建一个Rails 3应用程序,该应用程序将保存来自各种不同公司的产品。我想定义一大组字段,每个产品都可以选择适用于它的字段。

字段类型将是单行文本字段,多行文本字段,广播或选择选项,复选框选项,日期,持续时间或更自定义的内容。我需要能够根据此类型动态呈现字段以进行编辑和显示。

我目前的想法是使用MongoDB并将所有内容存储在产品的哈希中。

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

然后渲染新的/编辑字段,如:

= 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"

然后我对每个字段类型进行了部分编辑和显示。

创建后,mongodb中的产品可能如下所示:

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

这是一个好方法吗?

2 个答案:

答案 0 :(得分:5)

当然,这会起作用 - 但是你知道你不需要去Mongo只是为了能够在数据库中存储值的散列。您还可以将属性设置为serialize,然后Rails会将其转换为YAML并在返回的路上返回到(简单)对象。

对于您描述的模式,这是一种相当常见(且非常可行)的方法。

答案 1 :(得分:0)

您可以将这些字段定义为Mongoid :: Document字段,并使用Product.fields作为内省。然后,您可以利用ActiveModel的功能,例如验证,以及i18n(如果需要)。