Rails Turbo框架改造页面的URL与参数留存问题
针对你用Turbo Frames重构用户页面遇到的三个问题,以下是Turbo原生的解决思路:
问题1:初始加载URL不更新到默认user_program路径
Turbo Frame的data-turbo-action="advance"仅在Turbo驱动的导航(比如点击链接、Frame加载后续内容)时生效,初始页面渲染时不会主动更新URL。正确的做法是在控制器层面处理重定向:
在users_controller.rb的show动作中,当未指定user_program时,直接重定向到第一个user_program的路径,同时保留原查询参数:
def show @user = User.find(params[:id]) unless params[:user_program_id] || request.path.include?('user_programs') default_program = @user.user_programs.first redirect_to user_user_program_path(@user, default_program, request.query_params), status: :see_other end end
这样用户访问/users/2时会直接跳转到/users/2/user_programs/1?booking_id=21(如果有查询参数),URL自动更新,满足分享需求。
问题2:刷新正确路径仅显示框架内容
当直接访问/users/2/user_programs/1并刷新时,请求会打到user_programs_controller#show,默认只返回框架内容。需要在该控制器中判断是否为完整页面请求,若是则渲染包含Turbo Frame的用户页面:
在user_programs_controller.rb的show动作中:
def show @user = User.find(params[:user_id]) @user_program = @user.user_programs.find(params[:id]) # 非Turbo Frame请求时,渲染完整用户页面 render 'users/show' unless turbo_frame_request? end
这样刷新时会加载完整的用户页面,同时Turbo Frame会自动匹配当前路径的内容,既保留了正确URL,又显示完整页面结构。
问题3:初始查询参数在Turbo操作中丢失
所有涉及Turbo Frame的链接(包括Frame的src和下拉框选项)都需要带上当前的查询参数,确保参数传递:
在users/show.html.haml中:
- Turbo Frame的src包含查询参数:
= turbo_frame_tag 'user_program', src: user_user_program_path(@user, @user_program, request.query_params), data: { turbo_action: 'advance' }
- 下拉框的选项链接同样带上查询参数:
%select{ onchange: "Turbo.visit(this.value)" } - @user.user_programs.each do |program| %option{ value: user_user_program_path(@user, program, request.query_params), selected: program == @user_program } = program.name
这样无论是初始加载还是切换user_program,查询参数都会被保留在URL中。
内容的提问来源于stack exchange,提问作者Joseph Carpenter

