如何使用Rails Turbo Frames添加多个新条目并递增Frame ID?
解决方案
1. 批量新增页面(app/views/items/batch_new.html.erb)
先初始化索引,用父表单包裹所有子表单,方便后续批量提交:
<%= form_tag items_path, method: :post do %> <% current_index = 0 %> <!-- 存放所有新增表单的容器 --> <div id="items_container"></div> <!-- 添加按钮:传递当前索引,指定唯一的turbo frame目标 --> <%= button_to 'Add One', new_item_path(index: current_index), data: { turbo_frame: "new_item_#{current_index}" }, method: :get %> <!-- 隐藏的turbo frame,用来加载新表单 --> <%= turbo_frame_tag "new_item_#{current_index}" do %> <% end %> <!-- 批量提交按钮 --> <%= submit_tag 'Save All Items' %> <% end %>
2. 新条目页面(app/views/items/new.html.erb)
接收索引参数,生成唯一的frame ID,返回子表单同时更新下一个添加按钮的索引:
<% current_index = params[:index].to_i %> <% next_index = current_index + 1 %> <%= turbo_frame_tag "new_item_#{current_index}" do %> <!-- 将子表单插入容器 --> <%= content_tag :div, id: "item_form_#{current_index}" do %> <%= fields_for "items[#{current_index}]", Item.new do |f| %> <%= simple_form_for f do |form| %> <%= form.input :name %> <%= form.input :description %> <!-- 移除按钮:用Turbo直接删除当前表单 --> <%= button_tag 'Remove', type: 'button', data: { turbo_stream: true, action: "click->turbo#remove" } %> <% end %> <% end %> <% end %> <!-- 更新下一个添加按钮的参数和frame目标 --> <%= button_to 'Add One', new_item_path(index: next_index), data: { turbo_frame: "new_item_#{next_index}" }, method: :get %> <!-- 新增下一个隐藏的turbo frame --> <%= turbo_frame_tag "new_item_#{next_index}" do %> <% end %> <% end %>
3. 控制器修改(app/controllers/items_controller.rb)
支持批量参数处理,实现批量创建:
class ItemsController < ApplicationController def batch_new # 批量新增页面渲染,无需额外逻辑 end def create # 循环创建所有条目 items_params.each do |item_attrs| Item.create(item_attrs.permit(:name, :description)) end redirect_to items_path, notice: '所有条目已保存' end private def items_params params.require(:items).values end end
4. 路由修改(config/routes.rb)
添加批量新增的路由:
resources :items do get :batch_new, on: :collection end
错误原因说明
之前报param is missing or the value is empty: index,是因为按钮的链接没有传递index参数。现在通过new_item_path(index: current_index)主动传递索引,就能正常获取参数并实现递增,避免重复frame ID导致表单被替换。
内容的提问来源于stack exchange,提问作者Brian
相关产品推荐
相关产品推荐

