Rails:在Action间保存参数,实现预订日期默认值传递
我懂你想要实现的效果:在index页面选好日期区间搜索后,点进某个场地的show页面,预订表单里自动填上刚才选的日期,对吧?这个需求很常见,核心问题是HTTP是无状态的,index页面的params[:query1]和params[:query2]不会自动跟着页面跳转传到show页面,得手动把它们带过去。下面给你两种靠谱的实现方案:
方案一:通过URL查询参数传递(简单直观)
这种方式会把日期参数放在show页面的URL里,优点是简单直接,用户刷新页面后默认值还在。
第一步:修改index页面的场地链接
在index.html.erb里,找到指向场地show页面的链接(比如你可能写的<%= link_to space.name, space %>),把query1和query2作为查询参数加进去:
# index.html.erb 中指向show页面的链接 <%= link_to space.name, space_path(space, query1: params[:query1], query2: params[:query2]) %>
这样用户点击链接进入show页面时,URL会变成类似/spaces/1?query1=2024-05-01&query2=2024-05-03,show页面就能拿到这两个参数了。
第二步:优化show页面的预订表单
你现在的表单写法有个小细节可以调整:用f.label替代label_tag(和表单对象绑定更规范,自动生成正确的for属性),再加个.presence处理参数为空的情况(比如用户没搜索直接进show页面时,不会给日期框设空字符串):
# show.html.erb 的预订表单 <%= form_with(model: [@space, @booking], local: true) do |f| %> <%= f.label :check_in, "Check in" %> <%= f.date_field :check_in, value: params[:query1].presence, class: "form-control" %> <%= f.label :check_out, "Check out" %> <%= f.date_field :check_out, value: params[:query2].presence, class: "form-control" %> <%= submit_tag "Reserve", class: "btn" %> <% end %>
方案二:通过Session存储(URL更干净)
如果不想把日期参数暴露在URL里,可以用Rails的session来临时存储用户选的日期,优点是URL更简洁,适合不需要分享带日期的链接的场景。
第一步:在Spaces控制器的index动作里存Session
# app/controllers/spaces_controller.rb def index # 你的场地查询逻辑,示例写法: @spaces = if params[:query1].present? && params[:query2].present? Space.where("available_from <= ? AND available_to >= ?", params[:query2], params[:query1]) else Space.all end # 把用户选的日期存到session里 session[:check_in] = params[:query1] if params[:query1].present? session[:check_out] = params[:query2] if params[:query2].present? end
第二步:在show页面的表单里用Session值
# show.html.erb 的预订表单 <%= form_with(model: [@space, @booking], local: true) do |f| %> <%= f.label :check_in, "Check in" %> <%= f.date_field :check_in, value: session[:check_in].presence, class: "form-control" %> <%= f.label :check_out, "Check out" %> <%= f.date_field :check_out, value: session[:check_out].presence, class: "form-control" %> <%= submit_tag "Reserve", class: "btn" %> <% end %>
注意:session是和用户浏览器绑定的,用户关闭浏览器后session会失效,适合临时存储这类用户操作的上下文数据。
两种方案都能解决你的问题,选哪种看你对URL美观度和功能的需求~
内容的提问来源于stack exchange,提问作者user10511957

