首页 > 解决方案 > 使用 accept_nested_attributes_for 和 fields_for 创建控制器方法

问题描述

create我正在用 Rails 5.2.0 构建一个关于食谱的 Web 应用程序,我对控制器的方法有疑问。

这是我的模型:

class Recipe < ApplicationRecord
    belongs_to :user
    has_many :quantities
    has_many :ingredients, through: :quantities

    accepts_nested_attributes_for :quantities, allow_destroy: true
end

class Quantity < ApplicationRecord    
    belongs_to :recipe
    belongs_to :ingredient
end

class Ingredient < ApplicationRecord
    has_many :quantities
    has_many :recipes, through: :quantities
end

这里是创建新食谱的视图:

<%= form_for(@recipe) do |f| %>

    <%= f.label :name, "Name" %>
    <%= f.text_field :name %>

    <%= f.label :servings, "Servings" %>
    <%= f.number_field :servings %>


    <%= f.fields_for :quantities do |quantity| %>

        <%= f.hidden_field :_destroy, class: "hidden-field-to-destroy" %>

        <%= f.label :ingredient_id, "Ingredient Name" %>
        <%= f.text_field :ingredient_id%>

        <%= f.label :amount, "Amount" %>
        <%= f.number_field :amount %>

        <%= f.label :unit, "Unit" %>
        <%= f.select(:unit, ["kg","g","l","ml"], {include_blank: true}) %>
    <% end %>

    <%= f.submit 'Add new recipe' %>

<% end %>

我可以使用 jquery 动态添加新成分,也可以以相同的形式删除它们。

控制器的方法update完美运行,但该create方法不起作用:

class RecipesController < ApplicationController
    def create
        @recipe = current_user.recipes.build(recipe_params)
        if @recipe.save
            flash[:success] = "New recipe created correctly."
            redirect_to @recipe
        else
          render 'new'
        end
    end 

    def update
        @recipe = Recipe.find(params[:id])
        if @recipe.update_attributes(recipe_params)
          flash[:success] = "The recipe has been updated correctly."
          redirect_to @recipe
        else
          render 'edit'
        end
    end

    private
        def recipe_params
            params.require(:recipe).permit( :name, :servings, quantities_attributes: [:ingredient_id, :amount, :unit,:_destroy, :id, :recipe_id])
        end
end

我正在尝试这样做,@recipe = current_user.recipes.build(recipe_params)但在视图中出现以下错误:

我认为这是因为在尝试创建关系时,需要指明recipe_id,但尚未创建recipe,无法指明id。

您能否告诉我首先创建配方的正确方法是什么,然后能够通过配方​​控制器的创建方法中的数量添加成分?

标签: ruby-on-railsassociationsnested-attributes

解决方案


根据共享的消息, qunatity_recipes 不能为空,并且您没有指定任何条件来管理它。

当前的

class Recipe < ApplicationRecord
 belongs_to :user
 has_many :quantities
 has_many :ingredients, through: :quantities

 accepts_nested_attributes_for :quantities, allow_destroy: true
end

将配方类的接受嵌套属性更新为 allow_nil

class Recipe < ApplicationRecord
 belongs_to :user
 has_many :quantities
 has_many :ingredients, through: :quantities

 accepts_nested_attributes_for :quantities, allow_destroy: true, allow_nil: true
end

推荐阅读