为什么我在使用 accepts_nested_attributes_for 时无法保存我的嵌套属性
Why am I not able to save my nested attributes when I'm using accepts_nested_attributes_for
使用邮递员,我正在尝试 POST 一个具有标签和成分嵌套属性的新食谱。关系显示在下面的模型中。
#Recipe Model
class Recipe < ApplicationRecord
has_many :recipe_ingredients
has_many :recipe_tags
has_many :ingredients, :through => :recipe_ingredients
has_many :tags, :through => :recipe_tags
accepts_nested_attributes_for :ingredients, :tags
end
#Tag Model
class Tag < ApplicationRecord
has_many :recipe_tags
has_many :recipes, :through => :recipe_tags
def self.add_slugs
update(slug: to_slug(tag_name))
end
def to_param
slug
end
end
#Ingredient Model
class Ingredient < ApplicationRecord
has_many :recipe_ingredients
has_many :recipes, :through => :recipe_ingredients
end
#Join Table for recipe and ingredients
class RecipeIngredient < ApplicationRecord
belongs_to :recipe, optional: true
belongs_to :ingredient, optional: true
end
#Join Table For recipe and tags
class RecipeTag < ApplicationRecord
belongs_to :recipe, optional: true
belongs_to :tag, optional: true
end
这是我处理请求的食谱控制器。
class Api::RecipesController < ApplicationController
#before_action :authenticate_user
def index
@recipes = Recipe.all
render json: @recipes, status: 200
end
def create
@recipe = Recipe.new(recipe_params)
#ingredient = @recipe.ingredients.build
render json: @recipe, status: 200
end
def show
@recipe = Recipe.find(params[:id])
render json: @recipe, status: 200
end
private
def recipe_params
params.require(:recipe).permit(:name, :description, ingredients_attributes: [:id, :description], tags_attributes: [:id, :tag_name])
end
end
我从邮递员那里发送的参数是
{
"recipe":
{
"name": "Creamy Dill Chicken",
"description": "Dill has fresh and grassy flavor. Give it a small taste first if you are unfamiliar with the herb, and feel free to leave out some or all of it if too strong.",
"ingredients":[
{
"description": "Dill"
},
{
"description": "Yukon Gold Potatoes"
},
{
"description": "Asparagues"
},
{
"description": "Chicken Breasts"
},
{
"description": "Sour Cream"
},
{
"description": "Chicken Stock concentrate"
},
{
"description": "Dijon mustard"
}
],
"tags": [
{
"tag_name": "Home Cooking"
},
{
"tag_name": "American"
}
]
}
}
我得到的是一个新创建的食谱,但是配料和标签数组是空的。在我的控制台中,我得到
Unpermitted parameters: :ingredients, :tags
我想知道为什么在我使用 accepts_nested_attributes_for 时这些参数没有被保存。谢谢。
更新
问题在于 PostMan 中的正文以及将成分和标签更改为 ingredients_attributes 和 tags_attributes。下面是我的 RecipeController 的更新 rails 创建方法,用于实际创建食谱。谢谢!
def create
@recipe = Recipe.new(recipe_params)
@ingredients = recipe_params["ingredients_attributes"]
@tags = recipe_params["tags_attributes"]
@ingredients.each do |ingredient|
@recipe.ingredients.build(ingredient)
end
@tags.each do |tag|
@recipe.tags.build(tag)
end
if @recipe.save
render json: @recipe, status: 200
else
render json: @recipe.errors, status: :unprocessable_entry
end
end
那是因为您正在发送 Postman
不允许的属性。尝试修改 JSON 属性,特别是将 ingredients
替换为 ingredients_attributes
,将 tags
替换为 tags_attributes
。
你的最终 JSON body 应该是这样的:
{
"recipe":
{
"name": "Creamy Dill Chicken",
"description": "Dill has fresh and grassy flavor. Give it a small taste first if you are unfamiliar with the herb, and feel free to leave out some or all of it if too strong.",
"ingredients_attributes": [
...
],
"tags_attributes": [
...
]
}
}
使用邮递员,我正在尝试 POST 一个具有标签和成分嵌套属性的新食谱。关系显示在下面的模型中。
#Recipe Model
class Recipe < ApplicationRecord
has_many :recipe_ingredients
has_many :recipe_tags
has_many :ingredients, :through => :recipe_ingredients
has_many :tags, :through => :recipe_tags
accepts_nested_attributes_for :ingredients, :tags
end
#Tag Model
class Tag < ApplicationRecord
has_many :recipe_tags
has_many :recipes, :through => :recipe_tags
def self.add_slugs
update(slug: to_slug(tag_name))
end
def to_param
slug
end
end
#Ingredient Model
class Ingredient < ApplicationRecord
has_many :recipe_ingredients
has_many :recipes, :through => :recipe_ingredients
end
#Join Table for recipe and ingredients
class RecipeIngredient < ApplicationRecord
belongs_to :recipe, optional: true
belongs_to :ingredient, optional: true
end
#Join Table For recipe and tags
class RecipeTag < ApplicationRecord
belongs_to :recipe, optional: true
belongs_to :tag, optional: true
end
这是我处理请求的食谱控制器。
class Api::RecipesController < ApplicationController
#before_action :authenticate_user
def index
@recipes = Recipe.all
render json: @recipes, status: 200
end
def create
@recipe = Recipe.new(recipe_params)
#ingredient = @recipe.ingredients.build
render json: @recipe, status: 200
end
def show
@recipe = Recipe.find(params[:id])
render json: @recipe, status: 200
end
private
def recipe_params
params.require(:recipe).permit(:name, :description, ingredients_attributes: [:id, :description], tags_attributes: [:id, :tag_name])
end
end
我从邮递员那里发送的参数是
{
"recipe":
{
"name": "Creamy Dill Chicken",
"description": "Dill has fresh and grassy flavor. Give it a small taste first if you are unfamiliar with the herb, and feel free to leave out some or all of it if too strong.",
"ingredients":[
{
"description": "Dill"
},
{
"description": "Yukon Gold Potatoes"
},
{
"description": "Asparagues"
},
{
"description": "Chicken Breasts"
},
{
"description": "Sour Cream"
},
{
"description": "Chicken Stock concentrate"
},
{
"description": "Dijon mustard"
}
],
"tags": [
{
"tag_name": "Home Cooking"
},
{
"tag_name": "American"
}
]
}
}
我得到的是一个新创建的食谱,但是配料和标签数组是空的。在我的控制台中,我得到
Unpermitted parameters: :ingredients, :tags
我想知道为什么在我使用 accepts_nested_attributes_for 时这些参数没有被保存。谢谢。
更新
问题在于 PostMan 中的正文以及将成分和标签更改为 ingredients_attributes 和 tags_attributes。下面是我的 RecipeController 的更新 rails 创建方法,用于实际创建食谱。谢谢!
def create
@recipe = Recipe.new(recipe_params)
@ingredients = recipe_params["ingredients_attributes"]
@tags = recipe_params["tags_attributes"]
@ingredients.each do |ingredient|
@recipe.ingredients.build(ingredient)
end
@tags.each do |tag|
@recipe.tags.build(tag)
end
if @recipe.save
render json: @recipe, status: 200
else
render json: @recipe.errors, status: :unprocessable_entry
end
end
那是因为您正在发送 Postman
不允许的属性。尝试修改 JSON 属性,特别是将 ingredients
替换为 ingredients_attributes
,将 tags
替换为 tags_attributes
。
你的最终 JSON body 应该是这样的:
{
"recipe":
{
"name": "Creamy Dill Chicken",
"description": "Dill has fresh and grassy flavor. Give it a small taste first if you are unfamiliar with the herb, and feel free to leave out some or all of it if too strong.",
"ingredients_attributes": [
...
],
"tags_attributes": [
...
]
}
}