4

I have a parent model that has one child model with nested attributes. I have a single form that updates both parent and child.

Here are my models:

class Parent < ActiveRecord::Base
  has_one :child
  accepts_nested_attributes_for :child
end

class Child < ActiveRecord::Base
  belongs_to :parent
end

Form view:

<%= form_for @parent, do |f| %>
  <%= f.text_field :parent_name %>
  <%= f.fields_for @parent.child do |c| %>
    <%= c.text_field :child_name %>
  <% end %>
  <%= f.submit "Save" %>
<% end %>

Parent controller:

class ParentsController < ApplicationController      
  def update
    @parent = Parent.find(params[:id])    
    @parent.update(params.require(:parent).permit(:parent_name, child_attributes: [:child_name]))

    redirect_to @parent
  end
end

When I save the form, the parent updates but the child doesn't. What am I doing wrong?

2 Answers 2

7

You have a problem in the nested part of your form code, it should be

<%= form_for @parent, do |f| %>
  <%= f.text_field :parent_name %>
  <%= f.fields_for :child do |c| %>  <<<<<<<<<<< this line was wrong
    <%= c.text_field :child_name %>
  <% end %>
  <%= f.submit "Save" %>
<% end %>

You have to pass the id in the params attributes too :

@parent.update(params.require(:parent).permit(:parent_name, child_attributes: [:id, :child_name]))

Cheers

Sign up to request clarification or add additional context in comments.

2 Comments

That works, thanks! Why do I have to use the symbol and not the object?
1

In your controller

class ParentsController < ApplicationController      
  def edit
    @parent = Parent.find(params[:id])
    @child = @parent.child.build
  end
end

In your view

<%= form_for @parent, do |f| %>
  <%= f.text_field :name %>
  <%= f.fields_for @child do |builder| %>
    <%= builder.text_field :name %>
  <% end %>
  <%= f.submit "Save" %>
<% end %>

Assuming parent_name and child_name was here to illustrate your need. Your attributes should not be name-spaced like this.

You also have to pass the id in the permit method like this

child_attributes: [:id, :name]

Or using child_name

child_attributes: [:id, :child_name]

This is not well documented at this time.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.