Rails: 建立深层关联的形式

Rails: form to build deep associations

我正在尝试构建一个对象,该对象一次点击就有三个关联。如果需要,用户可以选择添加更多子对象。

class Template < ActiveRecord::Base
  has_many :stacks, dependent: :destroy
  accepts_nested_attributes_for :stacks, allow_destroy: true
end

class Stack < ActiveRecord::Base
  belongs_to :template
  has_many :boxes, dependent: :destroy
  accepts_nested_attributes_for :boxes, allow_destroy: true
end

class Box < ActiveRecord::Base
  belongs_to :stack
  has_many :template_variables, dependent: :destroy
  accepts_nested_attributes_for :template_variables, allow_destroy: true
end

class TemplateVariable < ActiveRecord::Base
  belongs_to :box
end

现在我的新模板控制器如下所示:

def new
  @template = Template.new
  stack = @template.stacks.build
  box = stack.boxes.build
  box.template_variables.build
end

我遇到了一些障碍,这让我觉得有更好的方法可以做到这一点。 Stack 对象下的对象未保存。控制器允许所有正确的参数。

params.require(:template).permit(:name,
  stacks_attributes: [:name, :direction, :order, :x, :y, :_destroy],
  boxes_attributes: [:name, :_destroy],
  template_variables_attributes: [:name, :box_name, :designator, :order_index, :_destroy])

可能是我的表单只是在必要时呈现的部分,如下所示:

<%= f.simple_fields_for :stacks do |stack| %>
  <%= render 'stack_fields', f: stack %>
<% end %>

<%= link_to_add_fields '+ stack', f, :stacks %>

后续关系嵌套在其中,如 stack_fields 部分:

<div style='background: #ccc; padding: 1em;'>
  <%= f.input :name  %>
  <%= f.input :direction %>
  <%= f.input :order %>
  <%= f.input :x %>
  <%= f.input :y  %>
  <%= f.hidden_field :_destroy %>
  <%= link_to 'x', '#', class: 'remove_fields' %>

  <%= link_to_add_fields '+ box', f, :boxes %>

  <%= f.simple_fields_for :boxes do |b| %>
    <%= render 'box_fields', f: b %>
  <% end %>
</div>

所以我的问题真的是:有没有比像这样上坡战斗更好的方法来实现我想要的?比如,也许有标准做法或 gem 或有助于 "deep" 对象关系创建的东西?

参数嵌套不正确,每个对象都必须嵌套在其父对象中。目前,您将它们全部嵌套在模板中。尝试:

params.require(:template).permit(:name,
  stacks_attributes: [
    :name, :direction, :order, :x, :y, :_destroy, 
    boxes_attributes: [
      :name, :_destroy, 
      template_variables_attributes: [
        :name, :box_name, :designator, :order_index, :_destroy
      ]
    ]
  ]
)

一般建议深度关联最多不超过 2 级。然而,有时这是不可避免的。不知道数据建模的上下文使得很难考虑替代方法是否可行。