【问题标题】:Rails _destroy field appearing twice in formRails _destroy 字段在表单中出现两次
【发布时间】:2020-04-06 15:22:15
【问题描述】:

我有两个模型,Preset 和 Plot,如下:

class Preset < ApplicationRecord
    belongs_to :user
    has_many :plots, :dependent => :destroy
    accepts_nested_attributes_for :plots, allow_destroy: true
end

class Plot < ApplicationRecord
    belongs_to :preset
    belongs_to :theme, optional: true
end

还有一个用于编辑预设的嵌套表单:

= form_with(model: @preset, local: true, method: "patch") do |f|
  = label_tag(:preset_name, "Preset name:")
  = text_field_tag(:preset_name, @preset.name)
  %br
  = f.fields_for :plots do |builder|
    %br
    = render 'editplot', f: builder
  %br

根据railscast 196,定义用于销毁绘图的复选框的部分_editplot:

= f.label(:name, "Change plot:")
= f.select(:name, options_for_select([['Existing Plot 1', 'Existing Plot 1'], ['Existing Plot 2', 'Existing Plot 2']]))
= f.label(:_destroy, "Remove plot")
= f.check_box(:_destroy)

我已经在预设控制器中允许了 _destroy 参数

def preset_params
            params.require(:preset).permit(:name, plots_attributes: [:id, :name, :parameter_path, :theme_id, :_destroy])
        end

编辑预设的所有其他方面都可以正常工作,但 _destroy 的复选框不能。编辑画面中销毁两个地块之一的参数在控制台中显示如下:

Parameters: {"authenticity_token"=>"TOKEN", "preset_name"=>"Preset", "preset"=>{"plots_attributes"=>{"0"=>{"name"=>"Existing Plot 1", "_destroy"=>"1", "id"=>"16"}, "1"=>{"name"=>"Existing Plot 1", "_destroy"=>"0", "id"=>"17"}}}, "commit"=>"Update Preset", "id"=>"25"}

“_destroy”=>“1”的存在表明这是按预期工作的。但是,当使用 Chrome 开发工具检查页面时,它显示在复选框旁边还有一个隐藏字段 &lt;input name="preset[plots_attributes][0][_destroy]" type="hidden" value="0"&gt;,其 _destroy 值在提交表单时也被传递。我有一种感觉,这个元素正在干扰表单,但我不确定它来自哪里或如何摆脱它。

我没有在此处包含它,但我有一些 JS 代码以相同的形式添加和删除“新绘图”部分,这些代码生成自己的 _destroy 字段。我不认为它们会成为问题的原因,但如有必要,我可以在编辑中添加此代码。

【问题讨论】:

  • 我不能很快地给你一个解决方案(而且我也认为这是一个非常狭窄的问题),但你应该记住,rails 在通过 with 生成复选框时有一些“特殊”行为表单助手。这就是隐藏输入字段的来源。尝试研究cocoon gem 及其内部工作原理。它甚至可能为您提供您想要的功能
  • 谢谢。似乎 cocoon 的工作方式与 railscast 中讨论的第二种方法类似,即链接到辅助方法而不是复选框。我已经在表单中实现了这个方法,它似乎可以工作(这是我在问题中提到的额外代码)但是有没有办法让复选框做我想做的事?如果没有,我会研究建议的方法,因为我知道它有效

标签: ruby-on-rails forms nested-attributes accepts-nested-attributes form-with


【解决方案1】:

这是checkbox documentation page 中解释的默认 Rails 行为。

【讨论】:

    【解决方案2】:

    正如 zwippie 所指出的,问题不在于复选框,而在于我的控制器。我试图在控制器中手动更新预设和绘图的属性(即使用像@plot.update(name: plot_name, parameter_path: _parameter_path) 这样的行)。因为我是手动执行此操作的,所以我实际上并没有处理 _destroy 参数,因此一旦从表单中传递了它,rails 就没有对它做任何事情。

    为了解决这个问题,我改用了@preset.update(preset_params),其中preset_params 表示控制器内允许的参数。只要 _destroy 被允许,它就会删除该对象。

    def preset_params
                params.require(:preset).permit(:name, plots_attributes: [:id, :name, :parameter_path, :theme_id, :_destroy])
            end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多