我有一个Restaurant
模型,其中包含许多DishCategory
个,并且还有Dish
个到DishCategory
的{{1}}个。{例如,类别晚餐将是与其相关的一些菜肴。为了帮助构建表单,我正在使用cocoon gem。
我熟悉为传统的嵌套表单设置视图代码,但现在我要更深入一层,我不知道如何编写以及在哪里放置菜肴的输入。我是否在我的部分内为simple_fields_for
设置了另一个dishes
块?按照文档,这是当前设置的方式:
模型
class Restaurant < ActiveRecord::Base
has_many :dish_categories, dependent: :destroy
has_many :dishes, through: :dish_categories, dependent: :destroy
accepts_nested_attributes_for :dish_categories, :reject_if => :all_blank, :allow_destroy => true
end
class DishCategory < ActiveRecord::Base
belongs_to :restaurant
has_many :dishes, dependent: :destroy
accepts_nested_attributes_for :dishes, :reject_if => :all_blank, :allow_destroy => true
end
class Dish < ActiveRecord::Base
belongs_to :dish_category
end
餐厅表格
<%= simple_form_for(@restaurant) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :name %>
</div>
<div class="form-inputs dish-category-inputs">
<%= f.simple_fields_for :dish_categories do |f| %>
<%= render 'dish_category_fields', f: f %>
<% end %>
</div>
<div class='add-dish-category'>
<%= link_to_add_association 'Add a Dish Category', f, :dish_categories %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
菜单类别字段
<div class="dish-category-form nested-fields">
<%= f.input :name %>
<%= link_to_remove_association "Remove Category", f %>
</div>
答案 0 :(得分:1)
所以看起来我确实需要创建一个额外的部分。根据我的理解,links_to_add_association
中的第三个参数需要与您希望嵌套的表单的模型相关联的部分参数。
菜单类别字段
<div class="dish-category-form nested-fields">
<%= f.input :name %>
<%= link_to_remove_association "Remove Category", f %>
</div>
<div class="form-inputs dish-category-inputs">
<%= f.simple_fields_for :dishes do |f| %>
<%= render "dish_fields", f: f %>
<% end %>
</div>
<div class='add-dish'>
<%= link_to_add_association "Add Dish", f, :dishes %>
</div>
菜字段
<div class="dish-category-form nested-fields">
<%= f.input :name %>
<%= link_to_remove_association "Remove Dish", f %>
</div>
注意:强>
当涉及到餐馆控制器代码时,它可能会让人们吵醒你的params白名单。将dishes_attributes
放在dish_categories_attributes
中以便正确保存所有内容非常重要:
餐厅控制器
class RestaurantsController < ApplicationController
...
private
def restaurant_params
params.require(:restaurant).permit(:name, dish_categories_attributes: [:id, :restaurant_id, :name, :_destroy, dishes_attributes: [:id, :dish_category_id, :name, :description, :_destroy]])
end
end
答案 1 :(得分:0)
是的,您需要在部分菜单中使用simple_fields_for。并且不要忘记在DishCategory模型中使用accepts_nested_attributes_for:菜肴。
答案 2 :(得分:0)
我有同样的问题,因为我努力让茧工作两个级别的has_many关联。就我而言,问题最终源于将茧与Trailblazer的改革形式对象结合使用。我发布了一个答案,以防其他人遇到同样的问题。
问题(这里:https://github.com/nathanvda/cocoon/blob/master/lib/cocoon/view_helpers.rb#L95)是cocoon将关联对象的嵌套字段基于模型的纯实例,而不是包含在Reform表单对象中的模型。 (不是批评,只是它的设计方式。)在你希望为嵌套对象上的关联渲染字段之前,这很好,因为嵌套属性的设置是在你的Reform表单对象中定义的,不是你的模特。
表单中的f.object
基本上是实际模型,而不是表单对象。除非模型本身配置了accept_nested_attributes,否则fields_for
不会将该属性视为nested_attributes_association
,并且html标记不会将这些字段命名为reform-rails可以将它们解析为正确嵌套的方式参数。
我的解决方案是使用wrap_object
来确保记录cocoon使用的是包含在相关表单对象中的模型,如下所示:
<%= link_to_add_association 'Add Supporting Image', f, :images, partial: 'web_app/report/supporting_image_fields', force_non_association_create: true, wrap_object: Proc.new {|image| Report::WebAppCreation::ImageWithoutHotspotsForm.new(image) } %>
(可能有更好的方法来获得相关的改革表格,但这给出了这个想法)。