我正在尝试在Rails 5中从一个表单创建一个recipe
对象和多个嵌套的ingredient
对象。就目前而言,我能够创建recipe
个对象,但是给出了传递params
以创建ingredient
对象时出错,特别是NoMethodError
:
undefined method `ingredient' for #<Ingredient id: nil, ing: "s", amount: "s", recipe_id: nil>
这是我的表格:
<%= form_for(@recipe, url: recipes_new_path) do |f| %>
<h1>
<%= f.label :name %><br>
<%= f.text_field :name %><br>
</h1>
<h1>
<%= f.label :steps %><br>
<%= f.text_area :steps %><br>
</h1>
<%= f.fields_for :ingredient do |p| %>
<h1>
<%= p.label :ing %><br>
<%= p.text_area :ing %><br>
</h1>
<h1>
<%= p.label :amount %><br>
<%= p.text_area :amount %><br>
</h1>
<% end %>
<%= f.submit "Add" %><br>
包含在routes.rb中:
....
resources :recipes do
resources :ingredients
end
包含在模特中:
class Ingredient < ApplicationRecord
belongs_to :recipe
....
end
class Recipe < ApplicationRecord
has_many :ingredients, dependent: :destroy
....
accepts_nested_attributes_for :ingredients, allow_destroy: true
validates_associated :ingredients
end
recipe
的控制器:
....
def new
@recipe = Recipe.new
@ingredient = @recipe.ingredients.build
end
def create
@recipe = Recipe.new(recipe_params)
@recipe.save
@ingredient = @recipe.ingredients.build(recipe_params[:ingredients_attributes])
if @ingredient.save
redirect_to recipe_path(@recipe)
else
render 'recipes/new'
end
end
....
def recipe_params
params.require(:recipe).permit(:name, :steps, ingredients_attributes: [:ing, :amount])
end
据我所知,我要么错误地传递params
来创建ingredient
对象,要么我不应该尝试在{{ingredient
中创建一个recipe
对象1}}控制器。
修改
从
更改表格<%= f.fields_for :ingredient do |p| %>
到
<%= f.fields_for :ingredients do |p| %>
修改
完整错误:
Started POST "/recipes" for ::1 at 2016-12-14 09:19:43 -0600
Processing by RecipesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"RfBXiL7vFla2/SvLqR2WrgzsfFMOqVRpjTavmvrPMJ/YBhF7UR+CeGV5NNRNyQfuALuJXc9hafPre+wPOo6n2A==",
"recipe"=>{"name"=>"a", "steps"=>"a", "ingredients_attributes"=>{"0"=>{"ing"=>"a", "amount"=>"a"}}},
"commit"=>"Add"}
(0.1ms) begin transaction
(0.1ms) rollback transaction
Completed 500 Internal Server Error in 37ms (ActiveRecord: 0.2ms)
NoMethodError (undefined method `ingredient' for #<Ingredient id: nil, ing: "a", amount: "a", recipe_id: nil>
Did you mean? increment):
app/controllers/recipes_controller.rb:14:in `create'
Rendering /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout
Rendering /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
Rendered /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (5.6ms)
Rendering /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
Rendered /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.8ms)
Rendering /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
Rendered /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (2.5ms)
Rendered /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (154.0ms)
Rendering /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/web-console-3.1.1/lib/web_console/templates/index.html.erb
Rendered /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/web-console-3.1.1/lib/web_console/templates/_markup.html.erb (0.7ms)
Rendering /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/web-console-3.1.1/lib/web_console/templates/console.js.erb within layouts/javascript
Rendering /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/web-console-3.1.1/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string
Rendered /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/web-console-3.1.1/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (1.5ms)
Rendering /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/web-console-3.1.1/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string
Rendered /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/web-console-3.1.1/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.9ms)
Rendering /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/web-console-3.1.1/lib/web_console/templates/style.css.erb within layouts/inlined_string
Rendered /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/web-console-3.1.1/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.6ms)
Rendered /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/web-console-3.1.1/lib/web_console/templates/console.js.erb within layouts/javascript (148.7ms)
Rendering /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/web-console-3.1.1/lib/web_console/templates/main.js.erb within layouts/javascript
Rendered /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/web-console-3.1.1/lib/web_console/templates/main.js.erb within layouts/javascript (0.6ms)
Rendered /Users/JCamp1991/.rvm/gems/ruby-2.3.1/gems/web-console-3.1.1/lib/web_console/templates/index.html.erb (284.4ms)
答案 0 :(得分:0)
我相信你只需要改变你的fields_for
使用“成分”复数:
<%= f.fields_for :ingredient do |p| %>
这是因为你的食谱has_many :ingredients
。如果您的食谱只有has_one :ingredient
,那么您的表单将按书面形式运行。
更新:您还应更改create
方法,如下所示:
def create
@recipe = Recipe.new(recipe_params)
if @recipe.save
redirect_to recipe_path(@recipe)
else
render 'recipes/new'
end
end
因为您将ingredients_params
传递给recipe
参数,所以您无需单独创建这些成分 - 它们将在配方模式下由accepts_nested_attributes_for
自动创建。
有关嵌套表单的永恒教程,请参阅Railscast上的Ryan Bates'Nested Model Form。