Thanks all, think I fixed it, mostly.
UsersController:
def create
@user = User.new(params[:user])
@person = @user.build_person(params[:user][:person])
@person.contacts_attributes = params[:person][:contacts]
if @user.save
flash[:notice] = ''User was successfully registered.''
redirect_back_or_default account_url
else
render :action => :new
end
end
def new
@user = User.new
@person = @user.build_person
@person.addresses.build
@person.phone_numbers.build
end
new.html.erb:
<h1>Sign up</h1>
<% form_for @user, :url => account_path do |f| %>
<%= f.error_messages %>
<%= render :partial => "form", :object => f %>
<p>
<%= f.submit "Register" %>
</p>
<% end %>
_form.html.erb
<%= error_messages_for :user %>
<div class="user">
<% form_for @user do |user_form| -%>
<%= user_form.label :email %>
<%= user_form.text_field :email %>
<br />
<%= user_form.label :password, user_form.object.new_record? ?
nil : "Change password" %>
<%= user_form.password_field :password %>
<br />
<%= user_form.label :password_confirmation, ''Confirm''
%>
<%= user_form.password_field :password_confirmation %>
<br />
<%= render :partial => "person", :object => @person %>
<% end -%>
</div>
<br />
_person.html.erb:
<div class="person">
<% fields_for @person do |person_form| -%>
<%= person_form.label :title %><%= person_form.select :title,
Person::TITLES %>
<%= person_form.label :first_name %><%person_form.text_field
:first_name %>
<%= person_form.label :last_name %><%person_form.text_field
:last_name %><br />
<br />
<%= person_form.label :job_title %><br />
<%= person_form.text_field :job_title %><br />
<br />
<div id="contacts">
<%= render :partial => "address", :collection =>
@person.addresses %>
<%= render :partial => "phone_number", :collection =>
@person.phone_numbers %>
</div>
<p>
<%= add_contact_link :address %>
<%= add_contact_link :phone_number %>
</p>
<% end -%>
</div>
_address.html.erb:
<div class="address">
<% fields_for "person[contacts][]", address do |contact_form|
-%>
<p>
Address<br/>
<%= contact_form.hidden_field :type %><br/>
<%= contact_form.select :label, Address::LABELS, :selected =>
Address::LABELS.first %>
Street <%= contact_form.text_field :value %><br/>
Zip+4 <%= contact_form.text_field :zip_plus_four, :limit => 10
%>
<%= remove_contact_link :address, ''remove'' %>
</p>
<% end -%>
</div>
And phone number is about the same as that.
The only problem is that it won''t save the contents of the :type
hidden_field in the last partial. It fails to validate. That''s a topic
for another post, though, I suppose.
On Sep 20, 11:01 pm, John Woods
<john.wo...-+ksaPUZU+wsI+954vlgkHg@public.gmane.org>
wrote:> Hi all,
>
> I have three models, like so:
>
> User
> belongs_to :person
> accepts_nested_attributes_for :person, :allow_destroy => false
> has_many :contacts
>
> Person
> has_many :contacts
> accepts_nested_attributes_for :contacts, :allow_destroy => true
>
> Contact
> belongs_to :person
>
> And actually, it''s a bit more complicated because Contact uses
single-
> table polymorphism and may be a PhoneNumber or an Address. Different
> information would be filled in for each on the form, so right now I
> have separate partials for each of those.
>
> My goal is to create both the User and the Person, as well as a
> Contact (if specified), when the first form is submitted. I''ve got
it
> so it creates the User and the Person, but it doesn''t set any of
the
> data in the Person row. It won''t create any Contacts at all.
>
> # new.html.erb
> <h1>Sign up</h1>
>
> <% form_for @user, :url => account_path do |f| %>
> <%= f.error_messages %>
> <%= render :partial => "form", :object => f %>
> <p>
> <%= f.submit "Register" %>
> </p>
> <% end %>
>
> # _form.html.erb
> <%= error_messages_for :user %>
> <div class="user">
> <% form_for @user do |user_form| -%>
>
> <%= user_form.label :email %><br />
> <%= user_form.text_field :email %><br />
> <br />
> <%= user_form.label :password, user_form.object.new_record? ?
> nil : "Change password" %><br />
> <%= user_form.password_field :password %><br />
> <br />
> <%= user_form.label :password_confirmation,
''Confirm'' %><br />
> <%= user_form.password_field :password_confirmation %><br
/>
> <br />
> <%= render :partial => "person", :object => @person
%>
> <% end -%>
> </div>
> <br />
>
> # _person.html.erb
> <div class="person">
> <% form_for @person do |person_form| -%>
>
> <%= person_form.label :title %><br />
> <%= person_form.text_field :title %><br />
> <br />
> <%= person_form.label :first_name %><br />
> <%= person_form.text_field :first_name %><br />
> <br />
> <%= person_form.label :last_name %><br />
> <%= person_form.text_field :last_name %><br />
> <br />
> <%= person_form.label :job_title %><br />
> <%= person_form.text_field :job_title %><br />
> <br />
> <div id="contacts">
> <%= render :partial => "address", :collection
=>
> @person.addresses %>
> <%= render :partial => "phone_number", :collection
=>
> @person.phone_numbers %>
> </div>
> <p>
> <%= add_contact_link :address %>
> <%= add_contact_link :phone_number %>
> </p>
> <% end -%>
> </div>
>
> # _phone_number.html.erb (_address is very similar)
> <div class="phone_number">
> <% new_or_existing = phone_number.new_record? ?
''new'' : ''existing''
> %>
> <% prefix =
"person[#{new_or_existing}_contact_attributes][]" %>
>
> <% fields_for prefix, phone_number do |contact_form| -%>
> <p>
> <%= contact_form.hidden_field :type %>
> Area + Phone <%= contact_form.text_field :value %><br/>
> <%= remove_contact_link :phone_number, ''remove''
%>
> </p>
> <% end -%>
> </div>
>
> # users_controller.rb
> def new
> @user = User.new
> @person = @user.build_person
> @addresses = @person.addresses.build
> @phone_numbers = @person.phone_numbers.build
> end
>
> # POST /users
> # POST /users.xml
> def create
> @user = User.new(params[:user])
> if @user.save
> flash[:notice] = ''User was successfully
registered.''
> redirect_back_or_default account_url
> else
> render :action => :new
> end
> end
>
> Any thoughts? Apologies if things are a little unorthodox. I''ve
been
> fiddling for hours.
>
> Thanks,
> John