Ruby on Rails中ActiveRecordModel重复返回同一实例:特性还是Bug?
ActiveRecord::RecordNotFound 异常原因及处理
核心原因分析
你的问题本质是ActiveRecord::Relation的上下文继承导致的,而非缓存机制问题:
- 当你调用
MyModel.where(some_column: "A").test2时,test2方法的执行上下文是这个where返回的ActiveRecord::Relation对象,而非MyModel类本身。 - 若你在
test2中误写为find(my_model.id)(而非MyModel.find),这个find会是Relation对象的方法,自动继承where(some_column: "A")的筛选条件。此时记录已被更新为some_column: "B",自然找不到,就会抛出你看到的异常。
如果代码确实是MyModel.find,那可能的其他原因:
- 模型定义了
default_scope -> { where(some_column: "A") },全局添加了该筛选条件,导致所有查询(包括find)都会带上这个条件。 - 存在
before_find回调,动态给查询添加了some_column: "A"的限制。
解决方案
明确全局查找,跳过上下文/scope
不管当前是否处于Relation上下文,用unscoped强制跳过所有筛选条件,确保查询全局的记录:MyModel.unscoped.find(my_model.id)检查并清理默认scope或回调
查看MyModel是否有default_scope或before_find回调,若不是业务必需,直接移除;若需要,可在查询时临时跳过:# 临时跳过default_scope MyModel.unscoped.find(my_model.id)确保更新操作生效
用带bang的update!替代update,若更新时触发验证失败会直接抛出异常,避免因更新未生效导致的逻辑问题:my_model.update!(some_column: "B")提前加载集合到内存
遍历前将Relation转为数组,避免后续操作继承Relation上下文:def self.test2 to_a.each do |my_model| my_model.update!(some_column: "B") MyModel.find(my_model.id) end end
内容的提问来源于stack exchange,提问作者dontStayHere
相关产品推荐
相关产品推荐

