【发布时间】:2012-07-13 10:21:22
【问题描述】:
我有一个 Rails 表单,其中包含一个父模型和另一个模型的可能多个子节点的嵌套属性。
子模型有一个属性,该属性在逻辑中作为数组进行操作,但使用 Rails 内置的序列化方法序列化为 YAML 字符串。
在表单中,我显示了数组的每个单独成员,以便用户可以选择性地删除成员。
当用户销毁所有成员时会出现问题。表单不会将参数的任何值传递给 Rails 控制器,当调用 UPDATE 操作时,它会忽略该属性,因为在表单参数哈希中没有它的键。这当然是复选框之类的已知问题,因此 Rails 会自动为每个复选框放置 2 个复选框 HTML 元素,一个隐藏的只有在复选框被选中时才会处理。
我在这里处理的不是复选框,而是隐藏的输入文本字段。
我实现的解决方案是直接在控制器的 UPDATE 动作中操作 params 哈希,像这样:
params[:series][:time_slots_attributes].each { |k,v| v[:exdates] ||= [] }
这算不算代码异味?
我是否应该添加一个额外的隐藏字段,该字段已禁用并且仅在用户删除最后一个成员时才启用?这个解决方案也很有效,但对我来说似乎很笨重。
【问题讨论】:
-
@Deefour,这并不能解决问题。问题是当 UPDATE 操作处理 params 哈希时,需要将一个空数组写入 DB。我想我可以检查 params 值以查看密钥是否存在,如果不存在,我可以酌情为每个孩子单独更新该属性。
-
类似这样的东西:
params[:series][:time_slots_attributes].each_with_index do |attribs,idx| @series.time_slots[idx].update_attribute(:exdates, []) unless attribs[1].has_key?(:exdates) end -
你问是不是代码异味;这是我唯一回应的一件事。
-
@Deefour,还好吧……谢谢。我正在寻找的是对为什么操纵 params 哈希是一种不好的做法的更深入的解释。如果我对所有影响有更广泛的了解,我可以更好地决定是否要在这个例外中违反最佳实践。
-
这是应该在模型中完成的应用程序逻辑(即将参数哈希传递给模型中的方法)。
标签: html ruby-on-rails ruby-on-rails-3 forms