10

I have a Person model and an Address Model:

class Person < ActiveRecord::Base
  has_one :address
  accepts_nested_attributes_for :address
end


class Address < ActiveRecord::Base
  belongs_to :person
end

In my people controller I have @person.build_address in my new action. My forms builds correctly. The problem is that when I submit the form, a person record and an address record is created but they aren't linked via the address_id column in the Person table.

Am I missing a step in the controller?

Thanks!

New Action UPDATE

def new
    @person = Person.new
    @person.build_address

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @person }
    end
  end

Form Code UPDATE

<%= form_for(@person) do |f| %>
  <% if @person.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@person.errors.count, "error") %> prohibited this person from being saved:</h2>

      <ul>
      <% @person.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :first_name %><br />
    <%= f.text_field :first_name %>
  </div>
  <div class="field">
    <%= f.label :last_name %><br />
    <%= f.text_field :last_name %>
  </div>
  <div class="field">
    <%= f.label :email %><br />
    <%= f.text_field :email %>
  </div>
  <div class="field">
    <%= f.label :telephone %><br />
    <%= f.text_field :telephone %>
  </div>
  <div class="field">
    <%= f.label :mobile_phone %><br />
    <%= f.text_field :mobile_phone %>
  </div>
  <div class="field">
    <%= f.label :date_of_birth %><br />
    <%= f.date_select :date_of_birth %>
  </div>
  <div class="field">
    <%= f.label :gender %><br />
    <%= f.select(:gender, Person::GENDER_TYPES) %>
  </div>
  <div class="field">
    <%= f.label :notes %><br />
    <%= f.text_area :notes %>
  </div>
  <div class="field">
    <%= f.label :person_type %><br />
    <%= f.select(:person_type, Person::PERSON_TYPES) %>
  </div>

<%= f.fields_for :address do |address_fields| %>
 <div class="field">
    <%= address_fields.label :street_1 %><br />
    <%= address_fields.text_field :street_1 %>
  </div>
 <div class="field">
    <%= address_fields.label :street_2 %><br />
    <%= address_fields.text_field :street_2 %>
  </div>
<div class="field">
    <%= address_fields.label :city %><br />
    <%= address_fields.text_field :city %>
  </div>
 <div class="field">
    <%= address_fields.label :state %><br />
    <%= address_fields.select(:state, Address::STATES) %>
  </div>
<div class="field">
    <%= address_fields.label :zip_code %><br />
    <%= address_fields.text_field :zip_code %>
  </div>
<% end %>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
2
  • Can you post your forms? You might be missing the nested fields_for. Commented Feb 22, 2011 at 3:29
  • Pretty sure now the problem is that you've got the association around the wrong way. See if my answer helps you. Commented Feb 22, 2011 at 10:02

2 Answers 2

16

You need to have accepts_nested_attributes_for :address on your Person model for this to work nicely. In your create action you can then do this:

def create
  @person = Person.new(params[:person])
  ...
end

Then Rails will take care of the rest.

UPDATE: if the address_id column is in the people table then it should be belongs_to :address, not has_one :address

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

2 Comments

Thank you! That was it. I must have searched high and low for problems with nested forms and it was my association the whole time. Thank you.
Just to clarify, I think he meant you need to have accepts_nested_attributes_for :address on your Person model (not Post). Great answer though!
0

Why is your address built in your new action, and not in the create action? You're building an address from a non saved model, without an id, so the foreign key can't be set. You should keep your @person in your new action, but put your build_address in your create action, after @person has been saved.

1 Comment

If I don't put @person.build_address in my new action, then the form doesn't show the address fields. I tried putting @person.build_address in the create action, but it only inserts a null record into the address table.

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.