Rails5升级出现Volunteer default event must exist报错的原因及修复方法
报错根本原因
- Rails 5 对
belongs_to关联的默认行为做了破坏性变更:默认所有belongs_to关联必填,保存时会自动校验关联对象存在,旧版本Rails中belongs_to默认是可选的,这是升级过程中最常见的关联校验类报错来源。 - 本次报错
ActiveRecord::RecordInvalid: Validation failed: Volunteer default event must exist直接对应VolunteerEvent模型中定义的belongs_to :volunteer_default_event关联,创建VolunteerEvent记录时没有传入关联的volunteer_default_event_id,触发了必填校验导致事务回滚。
触发位置
你在Roster模型的vol_event_for_date方法中调用VolunteerEvent.find_or_create_by创建记录时,仅传入了description和date两个字段,没有给volunteer_default_event关联赋值,导致创建失败。
修复方案
根据你的业务逻辑二选一即可:
方案1:保留必填校验,补全关联赋值
如果业务规则要求VolunteerEvent必须关联VolunteerDefaultEvent,修改创建逻辑,参考同模型下vol_event_for_weekday方法的逻辑,先获取/创建对应周几的默认事件,再赋值给新的VolunteerEvent:
def vol_event_for_date(date) # 获取对应周几的默认事件 default_event = vol_event_for_weekday(date.wday) # 创建时关联默认事件 VolunteerEvent.find_or_create_by(description: "Roster ##{self.id}", date: date) do |event| event.volunteer_default_event = default_event end end
方案2:关闭必填校验
如果业务上允许VolunteerEvent没有关联的VolunteerDefaultEvent,直接给关联加上optional: true参数,关闭Rails 5的默认必填校验:
class VolunteerEvent < ApplicationRecord # 新增optional: true参数 belongs_to :volunteer_default_event, optional: true validates_presence_of :date has_many :volunteer_shifts, :dependent => :destroy has_many :resources_volunteer_events, :dependent => :destroy validates_associated :volunteer_shifts # 其余代码不变 end
额外排查提示
你项目中所有belongs_to关联如果旧逻辑是可选的,都需要补加optional: true参数,比如:
Assignment模型下的belongs_to :attendance_type、belongs_to :call_status_typeVolunteerShift模型下的belongs_to :volunteer_default_shift、belongs_to :program
避免后续出现同类关联校验报错。
内容的提问来源于stack exchange,提问作者thefonso
相关产品推荐
相关产品推荐

