Rails 6使用嵌套属性更新User时关联Shop的ActiveStorage附件被删除如何解决
问题根因
你当前的参数写法不符合Rails嵌套属性的约定,直接传递shop字段触发了has_one关联的替换逻辑:系统会删除原有关联的Shop记录,再创建新的Shop记录关联到用户,原有Shop绑定的company_logo会随着Shop删除被自动清理,因此触发了ActiveStorage::PurgeJob任务。
解决方案
步骤1:修正模型嵌套属性配置
给accepts_nested_attributes_for添加update_only: true配置,作用是更新时直接修改已关联的唯一Shop对象,不会触发旧记录删除重建逻辑:
class User has_one :shop, dependent: :destroy # 当用户删除时同步删除关联店铺 accepts_nested_attributes_for :shop, update_only: true, reject_if: :all_blank end
如果不加
update_only: true,你需要在嵌套参数中额外传递现有Shop的id字段,否则系统依然会尝试创建新的Shop记录。
步骤2:修正更新参数的键名
Rails嵌套属性要求关联参数的键名为关联名_attributes,你需要把原有参数里的shop改为shop_attributes:
# 修正后的更新参数 params = {name: "TestUpdateName", shop_attributes: {name: "TestUpdateShop"}} User.last.update(params) User.last.shop.company_logo.attached? # 此时会返回 TRUE
步骤3:控制器强参数适配(Web请求场景需要)
如果更新逻辑在控制器中,需要在强参数中放行对应的嵌套字段:
def user_params params.require(:user).permit( :name, shop_attributes: [:id, :name, :company_logo] # 不需要更新logo的话也可以去掉:company_logo ) end
内容的提问来源于stack exchange,提问作者Jan
相关产品推荐
相关产品推荐

