有几个选项可以摆脱多选的空值。
与网络开发中的大多数事情一样,有上百万种方法可以给这只猫剥皮。
选项 1:JS 捕获和删除
如果您选择,您可以在 JS 中捕获表单,删除空字符串然后调用 form.submit -- 在这种情况下,对您而言,与其他选项相比没有真正的好处
选项 2:强参数控制器捕获
您可以在参数方法中使用拒绝空的方法
def object_params
obj_p = params.require(:user).permit(:primary_role, secondary_role: [] )
obj_p[:secondary_role].reject! { |role| role if role == ""}
up
end
选项 3:拒绝模型中的空白
#app/models/object_model.rb
before_save :remove_blanks
private
def remove_blanks
self.secondary_role.reject!(&:blank?).to_s
end
如果选项可能会在控制器之外更新,则 DRYer 方式在模型中。
编辑
如果您尝试捕获已删除的数组元素,则无法删除所有空白,如果数组中仍有一个项目(至少一个),它将起作用,但如果您删除所有元素,它根本不会将表单元素传递给控制器。
改为使用表单来指示用户设置为 nil 并使用上面的模型方法:
<%= f.input :secondary_role, :collection => UseridRole::VALUES, :include_blank => "Remove All Secondary Role(s)", :label => "Secondary Role(s):", :input_html => { :class => " simple_form_bgcolour simple_form_position overide_selection_field_width", :size => 4, multiple: true } %>
此外,如果选择了该选项,我可能会使用 javascript 取消选择其他所有内容,以便用户清楚将要发生的事情。
类似这样的js sn-p
var el = document.querySelector("#user_secondary_role")
el.addEventListener('change', function() {
if (el.value == "") {
roles = el.querySelectorAll("option")
for (var value of roles) {
(value.value == "") ? value.selected = true : value.selected = false
}
}
});
然后在您的模型中,对选项 3 中最后列出的 before_save 调用使用 remove_blanks 方法。
故障。这是正在发生的事情。
- 在您的表单元素中,继续并 include_blank - 如果元素为空,这将确保传递“”。接下来,确保 include_blank 有一个标题,其值将始终为“”,但您需要为用户提供一些可以点击的内容。
- 添加一些 javascript,以便当用户单击“删除所有次要角色”时 - 他们前面的表单会更改并取消选择其他选项。
- 模型方法将删除空白,简单明了,但除非您允许传入空白,否则这将不起作用,否则您的元素将是空的并且永远不会到达您的控制器/模型。您可以通过查看您的 development.log 并检查 POST 中传递的参数来验证这一点。