使用 simple_form 个条目输入空数组值
Empty array value being input with simple_form entries
我对 rails 和 simple_form 还是个新手,一直在尝试实现多个 select 选项来为用户提供多个角色。
当前输入如下所示
<%= f.input :secondary_role, :collection => UseridRole::VALUES, :include_blank => false,:label => "Secondary Role(s):", :input_html => { :class => " simple_form_bgcolour simple_form_position overide_selection_field_width", :size => 4, multiple: true } %>
所以,这确实有效,但在我的数组开头包含一个空值:
"secondary_role" : [
"",
"admin"
]
我有上面相同的代码,它适用于我的 primary_role 值,它是一个字符串,但是我的 secondary_role 可以有多个值,所以存储为一个数组。
我应该在哪里寻找解决这个问题的方法?
似乎 Rails 正在向集合中添加一个隐藏字段。尝试将 include_hidden: false
添加到您的表单输入中。
有几种方法可以避免 multi-selects 的空值。
与网络开发中的大多数事情一样,有一百万种方法可以给这只猫蒙皮。
选项 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 片段
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 这样当用户确实单击 "Remove All Secondary Roles" 时 - 他们前面的表单会更改并取消选择其他选项。
- 模型方法将删除空白,简单明了,但这将不起作用,除非您允许传入空白,否则您的元素将为空并且永远不会到达您的 controller/model .您可以通过查看 development.log 并检查 POST.
中传递的参数来验证这一点
我对 rails 和 simple_form 还是个新手,一直在尝试实现多个 select 选项来为用户提供多个角色。
当前输入如下所示
<%= f.input :secondary_role, :collection => UseridRole::VALUES, :include_blank => false,:label => "Secondary Role(s):", :input_html => { :class => " simple_form_bgcolour simple_form_position overide_selection_field_width", :size => 4, multiple: true } %>
所以,这确实有效,但在我的数组开头包含一个空值:
"secondary_role" : [
"",
"admin"
]
我有上面相同的代码,它适用于我的 primary_role 值,它是一个字符串,但是我的 secondary_role 可以有多个值,所以存储为一个数组。
我应该在哪里寻找解决这个问题的方法?
似乎 Rails 正在向集合中添加一个隐藏字段。尝试将 include_hidden: false
添加到您的表单输入中。
有几种方法可以避免 multi-selects 的空值。
与网络开发中的大多数事情一样,有一百万种方法可以给这只猫蒙皮。
选项 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 片段
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 这样当用户确实单击 "Remove All Secondary Roles" 时 - 他们前面的表单会更改并取消选择其他选项。
- 模型方法将删除空白,简单明了,但这将不起作用,除非您允许传入空白,否则您的元素将为空并且永远不会到达您的 controller/model .您可以通过查看 development.log 并检查 POST. 中传递的参数来验证这一点