我正在尝试保存一个包含配方和多种成分的对象。数据来自我的角度2应用程序,它将对象作为JSON传递。我的rails 5 api应用程序将接收配方对象并使用强参数将其直接保存到我的数据库。现在我可以将配方对象保存到数据库中,但由于某种原因,其中的成分未被保存。我检查了rails文档,我发现当前代码没有问题。任何想法都将不胜感激。
recipe.rb
class Recipe < ApplicationRecord
has_many :ingredients
accepts_nested_attributes_for :ingredients
end
ingredient.rb
class Ingredient < ApplicationRecord
belongs_to :recipe
end
recipe_controller.rb
def create
@recipe = Recipe.new(recipe_params)
if @recipe.save
render json: @recipe, status: :created, location: @recipe
else
render json: @recipe.errors, status: :unprocessable_entity
end
end
def recipe_params
params.require(:recipe).permit(:name , :description, :imagePath, ingredients_attributes: [ :id, :name, :amount])
end
我的控制台日志
Started POST "/recipes" for ::1 at 2017-01-09 11:40:44 +0900
ActiveRecord::SchemaMigrationLoad(0.3ms)SELECT`schema_migrations`.* FROM `schema_migrations`
Processing by RecipesController#create as HTML Parameters: {"name"=>"Spaghetti", "imagePath"=>"http://cdn2.tmbi.com/TOH/Images/Photos/37/300x300/exps36749_SD143203D10__25_1b.jpg", "description"=>"Delicious spaghetti", "ingredients"=>[{"name"=>"Tomato", "amount"=>1}, {"name"=>"Pasta", "amount"=>1}], "recipe"=>{"name"=>"Spaghetti", "description"=>"Delicious spaghetti", "imagePath"=>"http://cdn2.tmbi.com/TOH/Images/Photos/37/300x300/exps36749_SD143203D10__25_1b.jpg"}}
(0.1ms) BEGIN
SQL (0.2ms) INSERT INTO `recipes` (`name`, `description`, `imagePath`, `created_at`, `updated_at`) VALUES ('Spaghetti', 'Delicious spaghetti', 'http://cdn2.tmbi.com/TOH/Images/Photos/37/300x300/exps36749_SD143203D10__25_1b.jpg', '2017-01-09 02:40:44', '2017-01-09 02:40:44')
(0.7ms) COMMIT
Completed 201 Created in 9ms (Views: 1.0ms | ActiveRecord: 2.1ms)
答案 0 :(得分:1)
在Rails 5中,每当我们定义belongs_to关联时,都需要在https://github.com/rails/rails/pull/18937 change之后默认存在关联记录。 如果显示@ recipe.errors.messages,您将找到
{:"ingredient.recipe"=>["must exist"]}
只需添加&#39;可选:true&#39;到成分模型中的belongs_to行。
class Ingredient < ApplicationRecord
belongs_to :recipe, optional: true
end
答案 1 :(得分:0)
您的控制台日志显示参数包含密钥ingredients
。对于嵌套属性,您必须使用ingredients_attributes
。因此,请确保您的参数看起来像这样:
{
"name" => "Spaghetti",
"description" => "Delicious spaghetti",
"ingredient_attributes" => [
{"name" => "Tomato", "amount" => 1},
{"name" => "Pasta", "amount" => 1}
]
}
为什么我们不能在这里使用ingredients
?好吧,这将导致以下代码在内部执行:
recipe.ingredients = [{"name" => "Tomato", … }]
但是recipe.ingredients=
是关系的属性writer,它只接受Ingredient
个实例的数组。所以你必须像这样使用它:
recipe.ingredients = [Ingredient.new("name" => "tomato", …)]
在幕后,使用recipe.ingredients_attributes=
实际上是从普通哈希转换为Ingredient
的实例。