如何在Rails中遍历表单提交的多组start和end字段数据?
问题:处理Rails动态表单的多组start/end字段数据
之前我的Rails应用里,表单只会提交一组start和end字段,提交数据示例如下:
start: 2018-05-18 12:00 end: 2018-05-18 12:00
对应的后端处理代码是:
post "/time" do time = DoTime.new start = params["start"] finish = params["end"] time.started_at = start time.finished_at = finish time.profile = current_user time.save redirect "/profile" end
现在我改成了动态表单,用户可以多次复制start和end字段,提交后的数据变成了这样:
start: 2018-05-18 12:00 end: 2018-05-18 12:00 start: 2018-05-19 12:00 end: 2018-05-19 12:00
想请教下怎么用Ruby代码遍历每一组start和end,对每组数据执行上面的处理逻辑?
解决方案
嘿,这个场景我帮不少人处理过!其实核心是让Rails能正确识别多组参数,然后配对遍历处理,分两种情况来说:
1. 调整前端表单(推荐方案)
如果能修改前端的字段命名,把原来的name="start"改成name="start[]",name="end"改成name="end[]",这样提交后,Rails会自动把这些参数解析成数组。比如提交的数据会变成:
start[]: 2018-05-18 12:00 end[]: 2018-05-18 12:00 start[]: 2018-05-19 12:00 end[]: 2018-05-19 12:00
后端就能直接拿到params[:start]和params[:end]两个数组,然后用zip方法配对遍历,代码改成这样:
post "/time" do # 把start和end数组配对,每组对应一条记录 params[:start].zip(params[:end]).each do |start_time, end_time| next if start_time.blank? || end_time.blank? # 跳过空的字段组 time = DoTime.new( started_at: start_time, finished_at: end_time, profile: current_user ) time.save end redirect "/profile" end
这种方式最清晰,也不容易出错,因为Rails会帮我们把同组的参数对应好。
2. 无法修改前端时的兼容方案
如果前端已经固定不能改字段名,只能提交重复的start和end,Rails默认会把重复key的参数值解析成数组(单组提交时会是字符串)。这时候我们可以先把参数转成数组,再配对处理:
post "/time" do # 确保参数是数组,兼容单组和多组提交场景 start_times = Array(params[:start]) end_times = Array(params[:end]) start_times.zip(end_times).each do |start_time, end_time| next if start_time.blank? || end_time.blank? # 用create!可以在保存出错时抛出异常,方便调试 DoTime.create!( started_at: start_time, finished_at: end_time, profile: current_user ) end redirect "/profile" end
另外建议加上参数校验,比如检查时间格式是否合法、结束时间不早于开始时间,避免无效数据存入数据库~
内容的提问来源于stack exchange,提问作者DanTdd
相关产品推荐
相关产品推荐

