如何将空文本数组从视图传递到控制器以在 Rails 中进行更新?

How to pass an empty text array from view to controller for update in Rails?

我有一个模型,其文本数组字段定义如下

t.text "widgets", default: [], array: true 和我控制器中允许的参数

params.require(:model).permit(widgets: [])

在我看来,我可以使用看起来像

的输入字段来构建要放入此数组的值

<input multiple="true" value="widget_name" name="model[widgets][]" id="model_widgets"/>

这对于在数组中添加和删除值的所有情况都非常有效,但如果模型中已经存在,则从数组中删除最后一个值的情况除外

是否有一个神奇的隐藏输入可以用来将空数组传回控制器进行更新?

我知道复选框有类似的问题,您可以在其中使用值为 0 的隐藏字段。我试过使用类似的方法,例如

<input type="hidden" value="0" name="model[widgets][]" id="model_widgets"/> 其中 returns 控制器的数组,看起来像 ["0"](显然),

<input type="hidden" value="0" name="model[widgets]" id="model_widgets"/> 这是控制器中不允许的参数(因为它不是数组),甚至

<input type="hidden" value="[]" name="model[widgets]" id="model_widgets"/> - 也是不允许的,希望得到一个空数组。

我知道我可以通过在我的控制器中启用一个新参数来完成此任务,该参数在存在时表示一个空的小部件数组,但我希望从视图的角度来看有一个 "correct" 方法。

你试过了吗?:

<input name="model[widgets][]" type="hidden" value="" />

然后在控制器中做Array.wrap(params.dig(:model, :widgets)).reject(:blank?)分配?

答案似乎是否定的 - 没有神奇的隐藏输入可以将空数组传回控制器。由于模型不会为不存在的参数更新字段,因此应在控制器中使用默认值。

我找到了一种使用允许参数来完成此操作的优雅方法,我使用 rails 提供的 reverse_merge 来设置数组的默认值,这样如果它们被排除在 POST 参数它们将为空而不是不存在(即删除该参数的所有隐藏输入将导致使用空数组)。

def permitted_params
  defaults = { widgets: [] }
  params.require(:model).permit(widgets: []).reverse_merge(defaults)
end