Multi-model form saving and validation error problems

I have a form with fields from several models present.

My model relations are:

addresses has_many contacts
contacts has_one user
user belongs_to contact
contact belongs_to address

The code below works fine, but it’s ugly.

I think I ought to be able to just save the address, and everything
else should work automatically, but it doesn’t. (The address gets
written to the database, but not the user or the contact.)

E.g. I would like to write:

  Address.transaction do
    @address.save!
  end

rather than:

  Address.transaction do
    @address.save!
    @contact.address_id = @address.id
    @contact.save!
    @user.contact_id = @contact.id
    @user.save!
  end

Perhaps someone can point me in the right direction here…

Regards,

Chris

Working code:

the registration controller’s method is:

def register
if request.get?
session[:user_id] = nil
@user = User.new
@contact = Contact.new
@address = Address.new
else
@user = User.new params[:user]
@contact = Contact.new params[:contact]
@address = Address.new params[:address]
Address.transaction do
@address.save!
@contact.address_id = @address.id
@contact.save!
@user.contact_id = @contact.id
@user.save!
end
session[:user_id] = @user.id
render :action => :registered
end
#rescue
end

and the template’s code is:

<% @page_title = ‘register’%>
<%= error_messages_for ‘user’ %>
<%= error_messages_for ‘contact’ %>
<%= error_messages_for ‘address’ %>
<%= form_tag %>

name:
<%= select 'contact', 'title', %w{ Mr Miss Mrs Ms Dr Prof Sir } %> <%= text_field 'contact', 'firstname', :size => 15 %> <%= text_field 'contact', 'lastname', :size => 15 %>

phone:
<%= text_field 'contact', 'phone', :size => 10 %>

email: (needed to login to this site)<%= text_field 'user', 'email', :size => 20 %>

password:
<%= password_field 'user', 'password', :size => 10 %>

address:
<%= text_field 'address', 'line1', :size => 20 %>
<%= text_field 'address', 'line2', :size => 20 %>
<%= text_field 'address', 'town', :size => 20 %>
<%= text_field 'address', 'county', :size => 20 %>
<%= text_field 'address', 'postcode', :size => 10 %>

<%= submit_tag 'register' %>

<%= end_form_tag %>