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 允许您生成动态嵌套字段(任意多)。
所以我要做的是:
观看 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
子模型并允许销毁它。
现在,关于您的其余代码:
我认为您可能会使模型过于复杂。虽然我不知道您要处理的字段,但我的直觉是您没有必要使用多态关联。
乍一看我会这样设置
两个,也许三个模型:
- 订单
- 披萨
- 浇头? (茧的另一种用途)
Order
会 has_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
。
所以我是 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 允许您生成动态嵌套字段(任意多)。
所以我要做的是:
观看 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
子模型并允许销毁它。
现在,关于您的其余代码:
我认为您可能会使模型过于复杂。虽然我不知道您要处理的字段,但我的直觉是您没有必要使用多态关联。
乍一看我会这样设置
两个,也许三个模型:
- 订单
- 披萨
- 浇头? (茧的另一种用途)
Order
会 has_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
。