Rails使用collection_select保存关联预订时报Person/Car must exist错误
具体修复方案
1. 修正模型内的关联定义错误
Rails 要求belongs_to关联必须使用小写的符号名,不能直接用大写类名作为符号。你之前定义的:Person、:Car属于错误写法,会导致关联完全无法正常解析:
# 错误的原有代码 class Booking < ApplicationRecord belongs_to :Person belongs_to :Car end # 修正后的正确代码 class Booking < ApplicationRecord belongs_to :person belongs_to :car end
2. 修正迁移的字段生成逻辑
add_reference方法的第二个参数需要传入单数格式的关联模型名,不能传复数的表名。
你之前写的迁移用:people、:cars作为参数,实际生成的表字段是people_id、cars_id,和表单提交的person_id、car_id参数完全不匹配,后台根本接收不到关联ID的值,自然会触发关联存在性校验报错。
如果已经执行过错误的迁移,先回滚删除该迁移,重新修改为正确版本后再执行迁移:
class AddReferencesToBookingForPersonAndCar < ActiveRecord::Migration[6.1] def change # 传入单数模型名,自动生成对应外键字段:person_id关联people表、car_id关联cars表 add_reference :bookings, :person, foreign_key: true add_reference :bookings, :car, foreign_key: true end end
执行rails db:migrate更新表结构完成后,字段名就会和表单、控制器的参数名完全对齐。
3. 现有配置无需额外修改
你之前写的下拉选择表单、booking_params参数许可逻辑都是符合Rails规范的,只要上面两步的模型关联、表结构修正完成,选择的人员、车辆ID就能正常存入数据库,不会再弹出「Person must exist」「Car must exist」的错误提示。
补充说明:Rails 6 及以上版本默认开启
belongs_to的强制存在校验,只要关联名、外键字段名、前端提交参数名三者任意一个不匹配,都会触发这类校验报错。
内容的提问来源于stack exchange,提问作者OuttaSpaceTime
相关产品推荐
相关产品推荐

