Rails嵌套资源隐藏字段属性无法保存至数据库的问题求助
问题诊断与修复方案
看起来你遇到的问题是表单里明明填好了user_id和status值,却没法存入数据库,核心原因是参数处理逻辑和表单提交的结构不匹配,下面一步步给你拆解修复:
1. 修正MealPlansController的参数处理逻辑
你的MealPlansController里有两个关键错误:
- 没有定义
meal_plan_params强参数方法,直接调用params[:meal_plan_params]会拿到空值 - 表单提交的参数是
params[:meal_plan](因为form_for绑定的是[@recipe, MealPlan.new]),不是嵌套在recipe下的参数
修改meal_plans_controller.rb:
class MealPlansController < ApplicationController def create @recipe = Recipe.find(params[:recipe_id]) # 使用正确的强参数方法创建meal_plan @meal_plan = @recipe.meal_plans.create!(meal_plan_params) redirect_to @recipe end private # 定义MealPlan的强参数,允许user_id和status字段 def meal_plan_params params.require(:meal_plan).permit(:user_id, :status) # 注:recipe_id会通过路由自动关联到@recipe,不需要在参数里额外允许 end end
2. 移除RecipesController中多余的嵌套属性参数
你当前的表单并没有使用accepts_nested_attributes_for的嵌套提交方式(没有用fields_for),所以recipes_controller.rb里的meal_plans_params配置是多余的,可以删掉:
# 从recipe_params里移除这一行 meal_plans_params: [:recipe_id, :user_id, :status]
如果之后需要批量创建MealPlan再添加回来,现在单独创建的场景下不需要这个配置。
3. 可选优化:安全获取current_user的ID
表单里用了current_user["uid"],如果current_user是Devise生成的用户对象,更稳妥的写法是current_user.id,避免键名错误:
<%= f.hidden_field :user_id, value: current_user.id %>
为什么之前的代码失效?
- 表单提交的参数结构是
meal_plan[status]和meal_plan[user_id],但你之前试图从recipe的参数里读取嵌套的meal_plans属性,完全不匹配 - MealPlansController缺少正确的强参数过滤,Rails的强参数机制会自动拦截未被允许的参数,最终存入数据库的就是默认值
nil
修改后再测试提交,应该就能看到user_id和status正确存入数据库了。
内容的提问来源于stack exchange,提问作者Robinson
相关产品推荐
相关产品推荐

