You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails嵌套表单提交时仅向Booking添加1个Passenger对象问题排查

问题原因

  • 你的表单每次调用fields_for都绑定了同一个全局@passenger实例,生成的所有乘客输入框的name属性完全一致,浏览器提交时后输入的内容会直接覆盖之前的内容,所以最终只能拿到最后一位乘客的信息
  • 没有为Booking模型配置一对多关联的嵌套属性支持,fields_for无法识别你需要提交多个乘客的参数结构
  • 控制器new动作只初始化了1个乘客实例,没有根据需要的乘客数量提前为Booking实例构建对应数量的关联乘客对象

修复步骤

1. 配置Booking模型关联和嵌套属性

首先确保Booking模型和Passenger是一对多关联,开启嵌套属性支持:

class Booking < ApplicationRecord
  has_many :passengers
  # 开启乘客属性的嵌套写入支持
  accepts_nested_attributes_for :passengers
end

class Passenger < ApplicationRecord
  belongs_to :booking
end

2. 修改控制器逻辑

根据传入的乘客数量,提前为Booking实例构建对应数量的乘客关联对象,同时配置strong参数允许嵌套的乘客属性:

class BookingsController < ApplicationController
  def new
    @booking = Booking.new
    passenger_num = params[:passengers].to_i
    # 构建对应数量的乘客对象
    passenger_num.times { @booking.passengers.build }
  end

  def create
    @booking = Booking.new(booking_params)
    # 后续保存逻辑...
  end

  private
  def booking_params
    params.require(:booking).permit(passengers_attributes: [:name, :email])
  end
end

3. 简化表单逻辑

不需要自己写times循环,直接让fields_for遍历已经构建好的乘客关联集合,自动生成带索引的输入框:

<%= form_for @booking do |f| %>
  <%= f.fields_for :passengers do |addy_form|%>
    <%= addy_form.text_field :name, placeholder: "name" %>
    <%= addy_form.text_field :email, placeholder: "email"%>
  <% end %>

  <%= hidden_field_tag(:flight_id, params[:flight_id]) %>
  <%= hidden_field_tag(:scheduled_for, params[:scheduled_for]) %>
  <%= hidden_field_tag(:from_airport, params[:from_airport]) %>
  <%= hidden_field_tag(:to_airport, params[:to_airport]) %>

  <%= f.submit 'Confirm Booking' %>
<% end %>

修改后提交的参数会自动生成booking[passengers_attributes][0][name]、booking[passengers_attributes][1][name]这种带索引的结构,不会出现覆盖问题,所有乘客的信息都能正常提交。

内容的提问来源于stack exchange,提问作者Christian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 07:45:03