Rails: 不允许嵌套模型的 :id 导致自动生成新实例。为什么?

Rails: Not permitting :id of nested model leads to automatic generation of new instances. Why?

我对嵌套模型有一个概念上的疑惑,希望在这个问题上把自己说清楚。

我有 3 个模型,ABCA 接受 BC 的嵌套属性。在 AController#new 上我写了 @a = A.new, @a.b.build, @a.c.build (我将在下面分享代码)。

定义A的参数,我允许B的参数和C'参数。 问题:我忘记允许 C 的 :id

因此,每当我在我的网站上编辑 A 的实例时(例如,在“/a/1/edit”) , 它会自动创建 C.

的新实例

诊断问题非常简单(我只是发现 C 的 :id 丢失,并推断这是问题所在),但是我想知道为什么会这样。有没有人有见识?下面是我的代码的详细信息。

a.rb

has_many :b
has_many :c    
accepts_nested_attributes_for :b
accepts_nested_attributes_for :c

a_controlle.rb

def new
    @a = A.new
    @a = @a.b.build
    @a = @a.c.build
end

def edit
    @a = A.find(params[:id])
end

def update
    if A.find(params[:id]).update_attributes(a_params)
    #SOME CODE
end

def create
    @a = A.new(a_params)
    #SOME CODE
end

private

def a_params
    params.require[:a].permit(:a_name, b_attributes: [:id, :b_name],
    c_attributes: [:c_name]) ## SEE, I had forgotten C's :id.
end

并且 A/new.html.erb 和 A/edit.html.erb 都有 fields_for B 和 C.

所以,有谁知道为什么我访问 A/[:id]/edit 时它会生成新的 C 实例,因为我忘记了允许它的 :id?

这是设计使然。如果使用 accepts_nested_attributes_for :c 并发送 C 的属性,如果 C 的参数中没有 :id 参数(在 c_attributes 中),则创建该对象。 =26=]

所以我假设您有一个带有 CB 模型的嵌套属性的表单,并且每次您提交表单时都会发送 A、[=16= 的属性] 和 C 个对象。每次您发送 c_attributes 而没有 :id 时,都会创建新对象。

您可以仅对 A 对象或 AB 对象进行试验并创建表单,以查看未创建或编辑任何 C 对象。

我希望这能帮助您了解正在发生的事情。