Динамические поля с Rails 3 - PullRequest
7 голосов
/ 15 апреля 2011

У меня проблема с дизайном, которую я хочу пройти.

Я создаю приложение 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 ]

5 голосов
/ 15 апреля 2011

Конечно, это сработает - но знаете ли вы, что вам не нужно идти в Mongo, чтобы иметь возможность хранить хэш значений в БД. Вы также можете установить атрибут как serialize, тогда Rails преобразует его в YAML и обратно в (простой) объект на обратном пути для вас.

Это довольно распространенный (и очень выполнимый) подход к шаблону, который вы описываете.

0 голосов
/ 15 апреля 2011

Вы можете определить эти поля как поля Mongoid :: Document и использовать Product.fields в качестве самоанализа. Затем вы можете использовать функции ActiveModel, такие как проверки, а также i18n (при необходимости).

...