更换模型主键后Active Storage附件关联失效问题排查
更换模型主键为字符串后Active Storage附件关联异常(record_id存为0)
你的猜测完全正确——问题根源就是active_storage_attachments表的record_id字段默认是整数类型,而你新设置的主键encrypted_id是字符串类型,类型不匹配导致存储时字符串主键被强制转换为0。
下面是简便的修复步骤:
- 生成迁移修改record_id字段类型
执行命令生成迁移文件:
rails generate migration ChangeRecordIdTypeInActiveStorageAttachments
- 编辑迁移文件
打开生成的迁移文件,将record_id字段改为字符串类型(示例适配Rails 7+,可根据数据库类型调整细节):
class ChangeRecordIdTypeInActiveStorageAttachments < ActiveRecord::Migration[7.0] def change # 将record_id从integer改为string change_column :active_storage_attachments, :record_id, :string # 如果使用PostgreSQL,建议添加复合索引提升查询性能 # add_index :active_storage_attachments, [:record_type, :record_id] end end
- 运行迁移
执行迁移使修改生效:
rails db:migrate
- 确保Active Storage关联正确识别主键
虽然你已经在模型中设置了self.primary_key = 'encrypted_id',但保险起见可以显式在附件关联中指定主键(部分Rails版本可能需要这个显式声明):
修改Person模型的附件关联代码:
has_one_attached :photo, primary_key: :encrypted_id
- 清理错误数据(可选)
如果之前已经产生了record_id为0的无效附件记录,可以直接删除这些记录:
# 控制台执行,删除Person模型的无效照片附件 ActiveStorage::Attachment.where(record_type: 'Person', record_id: 0).destroy_all
最后重启服务器,重新测试附件上传功能即可。
内容的提问来源于stack exchange,提问作者doer123456789
相关产品推荐
相关产品推荐

