如何在Ruby on Rails中创建嵌套表单?

时间:2013-09-05 16:05:15

标签: ruby-on-rails nested-forms simple-form

我有跟随arragement

比萨模型,用于创建可由客户订购的比萨饼列表,也与订单相关联,以指示订购了哪个比萨饼。

class Pizza < ActiveRecord::Base  
  has_many :pizza_orders
  has_many :orders, :through => :pizza_orders
  has_and_belongs_to_many :toppings
end

选项模型,用于创建可与某些比萨相关联的选项列表,也与每个披萨订单的连接表相关联,以指定哪个披萨订购了顶部。

class Topping < ActiveRecord::Base
  has_and_belongs_to_many :pizzas
  has_and_belongs_to_many :pizza_orders
end

比萨饼和浇头的连接表,这是必需的,因为没有它,您无法指定哪些配料可以或不能与披萨一起订购。毕竟,将意大利辣味香肠打顶列入素食披萨可能会冒犯别人。

class PizzasToppings < ActiveRecord::Base
  belongs_to :pizza
  belongs_to :topping
end

订单模型,它只是将所有连接表保存在一起。

class Order < ActiveRecord::Base
  has_many :pizza_orders
  has_many :pizzas, :through => :pizza_orders
end

比萨饼和订单之间的连接表,这个多对多是一个有很多通过,而不是有一个属于很多,因为在Rails中你不能直接操作HBATM连接表(据我所知),而你需要能够因为选择关系而发货。

class PizzaOrder < ActiveRecord::Base
  belongs_to :pizza
  belongs_to :order

  has_and_belongs_to_many :toppings
end

连接表,用于指示为订单中的特定披萨选择了哪些配料。

class PizzaOrdersToppings < ActiveRecord::Base
  belongs_to :pizza_orders
  belongs_to :topping
end

然后我有一个管理页面来创建和关联比萨饼和浇头。

但我不知道如何创建订单表格。用户应该能够添加比萨饼并选择已经创建的一个或多个浇头

2 个答案:

答案 0 :(得分:2)

由ryan bates制作的有点旧的截屏Nested model form part 1,但我希望它对你有帮助,同时还有这个截屏的修订版。

答案 1 :(得分:1)

抱歉,我迟到了回复。

好的,没有测试过这个,但希望它能让你明白。为了使其起作用,此示例依赖于

  1. simple_form
  2. ryan bates动态嵌套表格
  3. 我必须道歉,这个答案缺少很大一部分,每次更改&lt;%= f.association:pizzas%&gt;时,您需要重新渲染link_to_add_fields部分。值,以便包含浇头的隐藏字段与已选择的比萨匹配。

    抱歉,我无法完全理解你,但我希望这能指明你正确的方向。

    _form.html.erb

    <%= simple_form @order do |f| %>
    
      <%= f.simple_fields_for :pizza_orders do |pizza_orders_fields| %>
        <%= f.association :pizzas %>
        <%= render partial: "pizza_order_fields", locals: {f: pizza_orders_fields}%>
        <%= link_to_add_fields "Add", f, :pizza_orders %>
      <% end %>
    <% end %>
    

    pizza_order_fields.html.erb看起来像

    <fieldset>
      <%= f.hidden_field :_destroy %>
      <%= link_to "Delete", '#', class: "remove_fields btn btn-danger" %>
      <%= f.association toppings_pizza_orders, collection: f.object.pizza.toppings %>
    </fieldset>