Postgresql JSONB 嵌套形式 ruby on Rails

问题描述 投票:0回答:2

我有产品作为活动记录表,选项_类型作为活动模型模型。选项类型是一个对象数组,如下所示,

[
  {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 ,以便用户可以添加各种选项名称及其值。怎么办?

参考链接如下,

使用 RubyOnRails 验证 jsonb 对象数组内的对象

ruby-on-rails activemodel nested-form-for
2个回答
0
投票

我知道这不是您希望的答案,但您应该尽可能以关系方式对其进行建模,而不是仅仅将所有内容都扔到 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 来完成。


0
投票

我最近遇到了类似的问题。所以我为这个确切的问题创建了一个简单的 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
© www.soinside.com 2019 - 2024. All rights reserved.