我有产品作为活动记录表,选项_类型作为活动模型模型。选项类型是一个对象数组,如下所示,
[
{name: 'color', values: ['red', 'blue']},
{name: 'size', values: ['small', 'medium']}
]
class OptionType
include ActiveModel::Model
attr_accessor :name, :values, :default_value
def initialize(**attrs)
attrs.each do |attr, value|
send("#{attr}=", value)
end
end
def attributes
[:name, :values, :default_value].inject({}) do |hash, attr|
hash[attr] = send(attr)
hash
end
end
class ArraySerializer
class << self
def load(arr)
arr.map do |item|
OptionType.new(item)
end
end
def dump(arr)
arr.map(&:attributes)
end
end
end
end
我想为 option_types 设计一个带有嵌套形式的 form_for ,以便用户可以添加各种选项名称及其值。怎么办?
参考链接如下,
我知道这不是您希望的答案,但您应该尽可能以关系方式对其进行建模,而不是仅仅将所有内容都扔到 JSONB 列中并希望得到最好的结果:
class Product < ApplicationRecord
has_many :options
has_many :product_options, through: :options
end
# rails g model option name:string product:belongs_to
class Option < ApplicationRecord
belongs_to :product
has_many :product_options
end
# rails g model product_option option:belongs_to name:string ean:string
class ProductOption < ApplicationRecord
belongs_to :option
has_one :product, through: :options
end
如果您的数据实际上结构足够好,您可以编写引用其属性的代码,那么 JSON 列并不是正确的答案。 JSON/数组也不是设置关联的正确答案。
这使您可以使用外键来维护引用完整性,并具有某种程度合理的模式和查询,而不仅仅是处理完全无结构的混乱。如果您必须处理可以具有不同类型的属性,例如可以是字符串、布尔值或数字的选项,您可以使用 JSON 列来存储值,以在一定程度上减轻旧 EAV 模式的缺点。
创建产品的变体可以根据您的要求通过单独的表单、嵌套属性或 AJAX 来完成。
我最近遇到了类似的问题。所以我为这个确切的问题创建了一个简单的 gem。
https://github.com/Pralish/acts_as_has_many
class Product < ActiveRecord::Base
acts_as_has_many :option_types
acts_as_accepts_nested_attributes_for :option_types
end
f.fields_for :option_types, @product.option_types |ff|
ff.text_field :name
ff.select :values, multiple: true