I have a conceptual doubt regarding nested models, and I hope I will make myself clear in this question.
I have 3 models, A, B, and C. A accepts nested attributes for B and C. On AController#new I write @a = A.new, @a.b.build, @a.c.build (I will share the code below).
Defining A's parameters, I permit B's parameters and C's parameters. Problem: I had forgotten to permit C's :id.
Thus, whenever I would edit an instance of A on my website (say, at '/a/1/edit'), it would automatically create new instances of C.
Diagnosing the problem was very easy (I just spotted that C's :id was missing, and inferred that it was the issue), but I wonder why that happens. Does anyone have insight? Details of my code follow.
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
And both A/new.html.erb and A/edit.html.erb have fields_for B and C.
So, does anyone know why anytime I would access A/[:id]/edit it would generate new instances of C, given that I had forgotten to permit its :id?
That's by design. If one use accepts_nested_attributes_for :c
and sends attributes for C
, that object is created if there is no :id
param in params for C
(in c_attributes
).
So I suppose you have a form with nested attributes for C
and B
models and every time you submit your form you send your attributes for A
,B
and C
objects. Every time you send your c_attributes
without :id
new object is created.
You can experiment and create form for only A
oject or A
and B
objects to see that no C
objects are created or edited.
I hope that helps you a bit to understand what's going on.