使用复选框以嵌套形式为嵌套属性预定义字段

Posted

技术标签:

【中文标题】使用复选框以嵌套形式为嵌套属性预定义字段【英文标题】:Pre-defined fields for nested attribute in nested form using checkbox 【发布时间】:2020-08-29 13:03:33 【问题描述】:

我有一个模型 Food,其中包含许多 food_varientsFoodVarient 是由系统管理员设置的模型。 例如食物种类可以是辣的、辣的、额外的奶酪等。食物可以有这些种类。

因为,Food has_many food_varients,我决定使用嵌套表单来让管理员创建一个新的food item并选择food_varients,食物可能来自管理员预先创建的预定义 food_varients

这就是我的FoodsController 的样子:

class FoodsController < DashboardBaseController

  # GET /foods/new
  def new
    @food = current_department.foods.new
    @food.food_varients.build
  end

  # GET /foods/1/edit
  def edit
  end

  def food_params
    params.require(:food).permit(:name, :description,food_varients_attributes[:id,:varient_id])
  end

end

我还接受了 Food.rb 文件中的嵌套属性,如下所示:

class Food < ApplicationRecord
 has_many :food_varients, dependent: :destroy
 has_many :varients, through: :food_varients, dependent: :destroy

 accepts_nested_attributes_for :food_varients, reject_if: proc  |attributes| attributes['varient_id'] == "0" 

这就是我的表格的样子,添加食物:

= form_for @food do |f|
  .field.form-group
    = f.label :name
    = f.text_field :name, class: 'form-control', tabindex: 1
  .field.form-group
    = f.label :description
    = f.text_area :description, class: 'form-control', tabindex: 3
   ........

//**Nested Form Starts from here**
    - current_department.varients.each do |varient|
      = f.fields_for :food_varients do |g|
        = g.label :varient_id, varient.title
        = g.check_box :varient_id, ,varient.id

我通过循环由管理员创建的 Varient 模型的每个实例创建了嵌套表单,并为管理员提供了将 food_varients 添加为的选项正在创建新的食物。

问题:

创建工作正常,嵌套属性按预期保存。 但是,当我尝试编辑 food item 时,嵌套表单显示重复字段。 例如: 如果最初将食物设置为具有变体(酸甜)。现在,食物项目的编辑页面向我显示了 4 个字段而不是两个字段,其中两个选中了糖醋字段,两个未选中。酸甜的田野。

有没有我必须尝试的不同方法?因为我看到的其他示例使用 text_fields 来动态保存嵌套属性,而我正在循环通过已经存在的 varient 实例。

【问题讨论】:

【参考方案1】:

这里根本不需要使用嵌套属性。只需使用集合助手和varient_ids= setter:

= form_for @food do |f|
  .field.form-group
    = f.label :name
    = f.text_field :name, class: 'form-control', tabindex: 1
  .field.form-group
    = f.label :description
    = f.text_area :description, class: 'form-control', tabindex: 3
  .field.form-group
    = f.label :varient_ids
    = f.collection_select :varient_ids, Varient.all, :id, :name
class FoodsController < DashboardBaseController
  # GET /foods/new
  def new
    @food = current_department.foods.new
  end

  # ...

  def food_params
    params.require(:food).permit(:name, :description, varient_ids: [])
  end
end

Rails 会自动添加/销毁连接表上的行。正确的拼写也是Variant:

变体(复数 变体

与类型或规范略有不同的事物。 - https://en.wiktionary.org/wiki/variant#English

【讨论】:

以上是关于使用复选框以嵌套形式为嵌套属性预定义字段的主要内容,如果未能解决你的问题,请参考以下文章

通过复选框Rails 4添加多个嵌套属性(可能有多种形式)

JavaScript,检查嵌套对象属性是不是为空/未定义的优雅方法[重复]

为啥在使用嵌套查询时不能引用用户定义的类型字段?

未调用自定义 Spring 注释

嵌套vs Elasticsearch中的对象

Rails 6嵌套形式茧不会保存子对象