Rails7.1.2+Ruby3.2.1无数据库列枚举报错求永久解决方案
解决方案
方法1:通过attribute显式声明属性类型(符合Rails规范)
Rails 7.1+要求枚举必须关联明确的属性类型,attr_accessor无法满足要求,因为它不会将属性注册到Rails的Active Model属性系统中。正确做法是用attribute声明属性的整数类型,同时可设置默认值,再定义枚举:
# 先声明属性类型,无需数据库列 attribute :status_ids, :integer, default: 0 attribute :type_ids, :integer, default: 0 # 再定义枚举 enum :status_ids, { pending: 0, verified: 1, work_in_progress: 2, complete: 3 } enum :type_ids, { price_variance: 0, oos_in_store: 1, not_in_store_file: 2, not_in_master_db: 3, data_not_correct: 4 }
这样attribute会把属性纳入Rails属性管理体系,让枚举识别到类型,默认值也能避免属性初始为空的问题。
方法2:纯Ruby自定义枚举(完全脱离Rails enum依赖)
如果不想依赖Rails的enum机制,可通过Ruby模块实现独立枚举功能:
module StatusIds PENDING = 0 VERIFIED = 1 WORK_IN_PROGRESS = 2 COMPLETE = 3 def self.to_h { pending: PENDING, verified: VERIFIED, work_in_progress: WORK_IN_PROGRESS, complete: COMPLETE } end def self.key(value) to_h.key(value) end def self.value(key) to_h[key] end end module TypeIds PRICE_VARIANCE = 0 OOS_IN_STORE = 1 NOT_IN_STORE_FILE = 2 NOT_IN_MASTER_DB = 3 DATA_NOT_CORRECT = 4 def self.to_h { price_variance: PRICE_VARIANCE, oos_in_store: OOS_IN_STORE, not_in_store_file: NOT_IN_STORE_FILE, not_in_master_db: NOT_IN_MASTER_DB, data_not_correct: DATA_NOT_CORRECT } end def self.key(value) to_h.key(value) end def self.value(key) to_h[key] end end
在模型中使用时,可添加辅助方法模拟Rails enum的行为:
class YourModel < ApplicationRecord attr_accessor :status_ids, :type_ids # 处理status_ids的赋值与取值 def status_ids=(value) @status_ids = if value.is_a?(Symbol) StatusIds.value(value) else value.to_i end end def status_ids @status_ids ||= StatusIds.value(:pending) end def status_name StatusIds.key(@status_ids) end # type_ids的辅助方法可参照上述逻辑实现 end
关键说明
方法1是最贴合Rails 7.1+规范的解决方案,若之前尝试attribute失败,大概率是未指定正确的类型(必须和枚举的数值类型匹配,这里是:integer)或未设置默认值。
内容的提问来源于stack exchange,提问作者Rizwan Basharat Ali
相关产品推荐
相关产品推荐

