Ruby on Rails创建Booking实例无法获取logement_id报错如何解决
你遇到的报错核心原因是提交预订表单时没有将logement_id传到BookingsController的create动作,你在ApplicationController定义的两个helper方法完全无法解决参数传递问题,因为HTTP请求是无状态的,不同请求之间的实例变量不会共享,你在pages#show里存的@logement_id到bookings#create的请求里已经被清空了。
修改步骤
- 新增表单隐藏字段传递logement_id
打开app/views/pages/show.html.erb,在form_with块内加入隐藏字段:
<%= form_with(model: @booking) do |form| %> <!-- 新增这行隐藏字段 --> <%= form.hidden_field :logement_id, value: @logement.id %> <%= form.label :start_booking %> <%= form.date_field :start_booking %> <%= form.label :end_booking %> <%= form.date_field :end_booking %> <%= form.submit "Reserver" %> <% end %>
- 放行booking_params的logement_id参数
打开app/controllers/bookings_controller.rb,修改booking_params方法允许接收logement_id:
def booking_params params.require(:booking).permit(:start_booking, :end_booking, :logement_id) end
- 清理冗余代码
- 删除ApplicationController里的
set_logement_id、get_logement_id方法和对应的helper_method声明,这部分代码没有实际作用 - 删除BookingsController的create动作里的
@booking.logement = Logement.find(set_logement_id)这行,因为参数里已经有logement_id,Booking.new(booking_params)会自动完成关联赋值
修改后的create方法可以简化为:
def create @booking = Booking.new(booking_params) @booking.user = current_user if @booking.save redirect_to booking_path(@booking) else render "new" end end
可选规范优化:使用嵌套路由
如果要更符合Rails REST规范,可以把预订路由嵌套在房源路由下,修改config/routes.rb:
resources :logements do resources :bookings, only: [:new, :create] end # 保留原有全局bookings路由用于其他操作 resources :bookings, only: [:index, :show, :edit, :update, :destroy]
对应修改show.html.erb里的表单和跳转链接,不需要再加隐藏字段,logement_id会直接从URL中获取:
<!-- 表单指定提交到嵌套路由 --> <%= form_with(model: [@logement, @booking]) do |form| %> <%= form.label :start_booking %> <%= form.date_field :start_booking %> <%= form.label :end_booking %> <%= form.date_field :end_booking %> <%= form.submit "Reserver" %> <% end %> <!-- 修改新建预订的跳转链接 --> <%= link_to "reserver", new_logement_booking_path(@logement) %>
内容的提问来源于stack exchange,提问作者Wiilfredmuffins
相关产品推荐
相关产品推荐

