Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 Nested Forms

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 %>
like image 754
Mike Avatar asked Feb 22 '11 03:02

Mike


1 Answers

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

like image 128
Ryan Bigg Avatar answered Nov 10 '22 13:11

Ryan Bigg