当表单引用多个模型时,允许在轨道中使用参数



我有三个模型。我遇到的两个(食谱和成分)彼此都有has_and_belongs_to_many关系。该表单似乎正在获取我要求的所有信息,但我似乎无法将成分的名称属性放入我允许的参数中。

形式:

<%= form_for(@recipe, :url => create_path) do |f| %>
<%= f.label :category %>
<%= f.select :category_id, options_for_select(Category.all.map{|c|[c.title, c.id]}) %>
<%= f.label :title %>
<%= f.text_field :title%>
<%= f.label :instruction %>
<%= f.text_area(:instruction, size: "50x10") %>
<%= f.fields_for :indgredient do |i| %>
    <%= i.label :name %>
    <%= i.text_field :name %>
<% end %>
<%= f.submit "Submit" %>

配方控制器中的相关操作:

def create
    safe_params = params.require(:recipe).permit(:title, :instruction,  
                                                 :category_id, {ingredient: :name})
    @recipe = Recipe.new(safe_params)
    @recipe.save
    @recipe.ingredients.create(name: safe_params[:name])
    render body: YAML::dump(safe_params)
end

YAML 转储给了我什么:

--- !ruby/hash:ActionController::Parameters
title: foo
instruction: bar
category_id: '1'

模型代码:

class Category < ActiveRecord::Base
  has_many :recipes
end
class Recipe < ActiveRecord::Base
  has_and_belongs_to_many :ingredients
  accepts_nested_attributes_for :ingredients
  belongs_to :category
end
class Ingredient < ActiveRecord::Base
  has_and_belongs_to_many :recipes
end

create方法确实会创建一个新成分,但名称为 nil。提前感谢您的帮助。

您是否在Recipe模型中添加了accepts_nested_attributes_for :ingredients

此外,还有一个 gem 可以处理嵌套形式,称为 cocoon .

您可以阅读这篇文章,其中确切地解释了您要做的事情。https://hackhands.com/building-has_many-model-relationship-form-cocoon/

首先,将<%= f.fields_for :indgredient do |i| %>更改为<%= f.fields_for :ingredients do |i| %>

并更改newcreate操作,如下所示

def new
  @recipe = Recipe.new
  @recipe.ingredients.build
end
def create
  @recipe = Recipe.new(safe_params)
  if @recipe.save
    redirect_to @recipe
  else
    render 'new'
  end
end
private
def safe_params
  params.require(:recipe).permit(:title, :instruction, :category_id, ingredients_attributes: [:name])
end

为了补充@Pavan的答案,你必须记住Ruby正在构建对象(它是一种面向对象的语言),因此,每当你传递相关数据时,你必须引用Ruby内存中的对象

在您的情况下,您正在尝试通过Recipe创建新的Ingredient对象:

#app/models/recipe.rb
class Recipe < ActiveRecord::Base
   has_and_belongs_to_many :ingredients
   accepts_nested_attributes_for :ingredients
end

。因此,您需要引用ingredients

<%= f.fields_for :ingredients do ... %>

--

您还需要确保仅在create操作中处理Recipe对象:

def create
    @recipe = Recipe.new safe_params
    @recipe.save
end
private
def safe_params
   params.require(:recipe).permit(:title, :instruction, :category_id, ingredients_attributes: [:name] )
end