Ruby 在 Rails 上:复杂表单生成

Ruby on Rails: Complex Form Generation

所以我是 Rails 的新手,我正在尝试找出生成复杂表单的最佳方法。基本思路是用户放置一个 order,每个 order 由一个或多个 pizza_order 组成,每个 pizza_order 由一个 special 披萨组成或者只是一个 pizza。我现在遇到的主要问题是如何生成动态表单,用户可以在其中持续生成任意数量的新 pizza_order 模型?

我的想法是有一个他们会按下的按钮,每次按下按钮时都会呈现一个局部视图,其中包含新 pizza_order 所需的字段。当用户按下提交时,将生成 order,以及与该 order 关联的新 pizza_order 模型数组。这些是我的模型到目前为止的样子。

订单

class Order < ActiveRecord::Base
  belongs_to :user
  has_many :pizza_orders
  accepts_nested_attributes_for :pizza_orders
end

披萨订单

class PizzaOrder < ActiveRecord::Base
  belongs_to :pizza, polymorphic: true
  belongs_to :order
end

披萨

class Pizza < ActiveRecord::Base
  has_and_belongs_to_many :toppings
  has_many :pizza_orders, as: :pizza
  belongs_to :crust
  validates :crust, presence: true
end

特别

class Special < ActiveRecord::Base
  belongs_to :pizza
  validates :pizza, :presence => true
  validates :cost, :presence => true
end

我对控制器和视图的外观一无所知,到目前为止,这是我视图的总体布局,稍后我会担心填充属性,我更关心的是获取适当的 rails 字段设置。

<%= form_for @order do |t| %>
  <%= t.fields_for t.pizza_orders do |po| %>
  <% end%>

  <!--Insert new pizza_orders after marker -->
  <span id="marker"></span>
  <%= button_tag "New Order", :type => 'button', :id => 'test' %>
  <%= t.submit "Place Order" %>
<% end %>

如果我对您的困境的理解正确的话,这就是 Cocoon 的工作! Cocoon 允许您生成动态嵌套字段(任意多)。

所以我要做的是:

install the cocoon gem

观看 this video 您可以快进到他展示如何向食谱中动态添加配料的位置,但实际上整个教程是一个很棒的参考,可以让您省去大量的谷歌搜索。

然后在你的披萨订单视图中,渲染部分(就像你说的)只用 cocoon 做。

<%= simple_form_for @order do |t| %>
  <%= t.simple_fields_for :pizza_orders do |po| %>
        <%= render 'order_fields', p: po %>
  <% end%>
    <div class="add-field"><%= link_to_add_association 'Add Pizza Order', t, :pizza_orders %></div>

  <!--Insert new pizza_orders after marker -->
  <span id="marker"></span>
  <%= button_tag "New Order", :type => 'button', :id => 'test' %>
  <%= t.submit "Place Order" %>
<% end %>

然后创建部分 _order_fields.html.erb 并按如下所示放置您需要的任何字段:

<div class="nested-fields">
  <%= p.input :order_field1 %>
  <%= p.input :order_field2 %>
  <%= p.input :order_field3 %>
  <%= link_to_remove_association "Delete", p %>
</div>

记得像任何其他嵌套一样执行强参数,您应该准备就绪!还要确保父模型 accepts_nested_attributes_for 子模型并允许销毁它。

现在,关于您的其余代码: 我认为您可能会使模型过于复杂。虽然我不知道您要处理的字段,但我的直觉是您没有必要使用多态关联。
乍一看我会这样设置 两个,也许三个模型:

  1. 订单
  2. 披萨
  3. 浇头? (茧的另一种用途)

Orderhas_many :pizzas

关于饼皮类型、披萨价格的数据将保存在每个披萨的模型中。像这样:rails g model Pizza price:decimal crust:string type:string。如果是特殊的,让类型为 "special."

额外的模型关联会使您的代码变得混乱,阻碍您使用可用的工具,并可能导致血压升高。披萨是生活中一种简单的乐趣,应该摆脱多态联想的负担;为了你自己,不要把它复杂化。 :-D

编辑

你需要Simple Forms gem直接复制我上面的内容。 (我强烈推荐。)请注意,您需要将 form_for 更改为 simple_form_for,将 fields_for 更改为 simple_fields_for