Rails嵌套属性更新时触发Record Not Found错误求助
问题描述
更新支持嵌套属性的记录时出现以下错误:
Couldn't find ServingV2 with ID=843 for RecipeServingV2 with ID=151
但直接查询数据库时,两条记录均存在:
> ap RecipeServingV2.find(151) RecipeServingV2 Load (1.1ms) SELECT "recipe_serving_v2s".* FROM "recipe_serving_v2s" WHERE "recipe_serving_v2s"."id" = $1 LIMIT $2 [["id", 151], ["LIMIT", 1]] #<RecipeServingV2:0x000000011d6fc228> { :id => 151, :serving_id => 843, :recipe_id => 1722, :ingredient_id => 92, :quantity => 2, :fractional => nil, :created_at => Thu, 29 Jun 2023 12:36:52.200198000 EDT -04:00, :updated_at => Thu, 29 Jun 2023 12:36:52.200198000 EDT -04:00 } > ServingV2.find(843) ServingV2 Load (4.2ms) SELECT "serving_v2s".* FROM "serving_v2s" WHERE "serving_v2s"."id" = $1 LIMIT $2 [["id", 843], ["LIMIT", 1]] => #<ServingV2:0x000000011d8ceec0 id: 843, description: "'1 tbsp' converted to 1 tablespoon", measurement_description: "'serving' converted to 1 tablespoon", unit: "tbsp", amount: 1, ingredient_id: 92, coachcare_id: "22349718", created_at: Thu, 29 Jun 2023 12:36:52.195844000 EDT -04:00, updated_at: Thu, 29 Jun 2023 12:36:52.208951000 EDT -04:00>
错误触发于控制器的@recipe.update(recipe_params)行,日志显示实际查询的是ServingV2 ID=833,随后事务回滚:
ServingV2 Load (2.6ms) SELECT "serving_v2s".* FROM "serving_v2s" WHERE "serving_v2s"."id" = $1 LIMIT $2 [["id", 833], ["LIMIT", 1]] ↳ app/controllers/recipes_controller.rb:308:in `block in update' TRANSACTION (51.2ms) ROLLBACK ↳ app/controllers/recipes_controller.rb:308:in `block in update'
可能的原因分析
- 嵌套参数中的
serving_id被错误覆盖:检查recipe_params的结构,大概率前端提交的参数里,针对RecipeServingV2 ID=151的嵌套数据中,serving_id被设置成了833而非843。Rails处理嵌套属性更新时,会优先使用参数里的值关联,而非数据库已有值,因此会去查找不存在的833,导致报错。 - 参数强过滤遗漏或篡改:如果
recipe_params未正确允许serving_id字段,或者在参数过滤过程中意外修改了该值,会导致Rails使用错误ID查找关联记录。 - 并发数据修改:如果在查询数据库和执行更新之间,有其他操作修改了RecipeServingV2的
serving_id为833,也会引发该问题。可检查更新请求前后的数据库记录变化,或调整数据库事务隔离级别排查。 - 嵌套属性配置冲突:如果
accepts_nested_attributes_for配置了特殊约束,或参数中包含错误的_destroy标记,可能触发异常查询,但从日志看核心问题是ID错误,此情况概率较低。
内容的提问来源于stack exchange,提问作者Jeremy Thomas
相关产品推荐
相关产品推荐

