【问题标题】:Using submodel accessor (STI) on parent params for nested forms在嵌套表单的父参数上使用子模型访问器 (STI)
【发布时间】:2017-10-03 22:19:03
【问题描述】:

我有以下型号:

class Order < ApplicationRecord
class Bill < Order
class Preorder < Order

class Detail < ApplicationRecord
class Metric < Detail
class Unit < Detail

模型Order 接受Detail 的嵌套属性,Order 可以是BillPreorderDetail 可以是UnitMetric

我正在使用 jsonb_accessor gem 为 UnitMetric 创建附加属性

class Metric < Detail
    jsonb_accessor :data,
      height: :decimal,
      width: :decimal
end

class Unit < Detail
    jsonb_accessor :data,
      quantity: :decimal
end

在我看来,我正在使用 Cocoon gem 为 UnitMetric 生成字段

<%= link_to_add_association(I18n.t('activerecord.models.metric.add'), f, :details, data: {association_insertion_node: '#details', association_insertion_method: :append}, :class => "btn btn-success", 
wrap_object: Proc.new { |detail| detail.type = "Metric"; detail = Metric.new }) %>
<%= link_to_add_association(I18n.t('activerecord.models.unit.add'), f, :details, data: {association_insertion_node: '#details', association_insertion_method: :append}, :class => "btn btn-success",
wrap_object: Proc.new { |detail| detail.type = "Unit"; detail = Unit.new }) %>

在我的控制器中,我有这个方法来验证参数

def order_params(type)
  if type=="Bill"
    params.require(:bill).permit(:client_id, :type, :delivered, :paid, :total_paid, details_attributes: [:id, :total_price, :type, :data, :service_id, :_destroy])
  elsif type=="Preorder"
    params.require(:preorder).permit(:client_id, :type, :delivered, details_attributes: [:id, :total_price, :type, :data, :service_id, :_destroy])
  end
end

表单工作得非常完美,它存储了我在表单中输入的所有数据,除了:width, :height, :quantity,当我把它们放在参数中时,它给出一个错误,说这些参数不属于细节模型,当我把@ 987654338@ 而不是,该列仍然是空的。

我正在考虑,直接为父模型 Detail 使用列,而不是使用 jsonb_accessor,或者为每个 MetricUnit 模型使用单独的视图和控制器,但我将这些解决方案作为最后的手段,因为我想保留代码更干,尽可能少用列

【问题讨论】:

    标签: ruby-on-rails ruby strong-parameters jsonb cocoon-gem


    【解决方案1】:

    恕我直言,问题是您正在使用关联details,这意味着rails 正在尝试创建/保存Detail。相反,您必须使用 unitsmetrics 各自的关联,因此 rails 知道创建正确的对象,该对象具有各自的 jsonb_accessors 以正确保存。

    您可以在模型中添加关联:

    has_many :metrics 
    has_many :units 
    

    我知道这在您的 UI 中可能不那么干净(如果所有内容都是细节,您可以将它们添加/列出在一起)。另一种选择是在 Detail 模型中定义所有可能的 json 字段(但不完全确定这是否违背了首先使用它们的目的)。

    【讨论】:

    • 它起作用了,我按照您的建议为度量和单位添加了has_many 关联,并将details_parameters 中的:data 替换为:quantity:widht:height。对于 UI,你是对的,度量宽度和高度输入不在同一行,但这个问题来自 simple-form-b​​ootstrap 包装器。并且即将将所有字段放入详细信息表中,如果稍后我可以添加一个新的详细信息类型,例如Duration &lt; Detail,它有时间作为属性,那么我必须创建新的迁移以将列时间添加到详细信息表。所以我选择了 jsonb 以获得更大的灵活性
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多