使用Acts as Paranoid gem添加非空列时遇软删除记录问题
解决Acts as Paranoid下给软删除记录添加非空jti列的问题
你遇到的核心问题是Acts as Paranoid会拦截对已标记为删除的记录的实例更新操作,导致无法通过update_column给软删除的User设置jti值,最终在添加非空约束时触发报错。
解决方案:直接用SQL批量更新所有记录
绕过ActiveRecord的实例方法限制,直接执行SQL语句更新所有用户(包括软删除的)的jti字段,具体迁移代码如下:
def change # 1. 先添加允许为空的jti列 add_column :users, :jti, :string # 2. 用SQL批量更新所有用户(含软删除)的jti值,避开Acts as Paranoid的拦截 execute <<-SQL UPDATE users SET jti = #{ActiveRecord::Base.connection.quote(SecureRandom.uuid)} WHERE jti IS NULL; SQL # 可选:验证所有记录都已设置jti(调试用) missing_jti = User.with_deleted.where(jti: nil).count p "Users missing jti: #{missing_jti}" # 此时应输出0 # 3. 修改列为非空约束 change_column_null :users, :jti, false end
优化补充
如果担心批量更新时用同一个UUID(概率极低),可以直接用数据库内置的UUID生成函数,性能更高效:
- PostgreSQL:
UPDATE users SET jti = gen_random_uuid() WHERE jti IS NULL; - MySQL:
UPDATE users SET jti = UUID() WHERE jti IS NULL;
内容的提问来源于stack exchange,提问作者Jeremy Thomas
相关产品推荐
相关产品推荐

