I thought I had this fixed, but apparently not. It works okay from the
console, but not from the view. I have the following:
# partial schema
create_table "users", :force => true do |t|
t.string "login", :null => false
t.string "first_name"
t.string "last_name"
t.string "email", :null => false
t.string "password", :null => false
t.integer "contact_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "contacts", :force => true do |t|
t.string "company_name"
t.integer "address_id"
t.integer "phone_areacode", :limit => 3
t.integer "phone_prefix", :limit => 3
t.integer "phone_suffix", :limit => 4
t.integer "phone_extension", :limit => 5
t.string "website"
t.integer "biztype_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "addresses", :force => true do |t|
t.string "street_address1"
t.string "street_address2"
t.string "city"
t.integer "state_id"
t.integer "zipcode"
t.integer "plus4"
t.datetime "created_at"
t.datetime "updated_at"
end
# relevant models
class User < ActiveRecord::Base
belongs_to :contact
has_many :properties
has_many :notes, :through => :properties
accepts_nested_attributes_for :contact, {
:allow_destroy => true,
:reject_if => :all_blank
}
end
class Contact < ActiveRecord::Base
has_one :user
belongs_to :address
belongs_to :biztype
accepts_nested_attributes_for :address, {
:allow_destroy => true,
:reject_if => :all_blank
}
end
class Address < ActiveRecord::Base
has_one :contact
has_one :property
belongs_to :state
end
# controller
def new
@user = User.new
@user.build_contact.build_address
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @user }
end
end
def edit
@user = User.find(params[:id])
end
When I run on the console, I can create a new user object with nested
attributes like so:
>> user=User.new
=> #<User id: nil, login: nil, first_name: nil, last_name: nil, email:
nil, password: nil, contact_id: nil, created_at: nil, updated_at: nil>
>> user.build_contact.build_address
=> #<Address id: nil, street_address1: nil, street_address2: nil, city:
nil, state_id: nil, zipcode: nil, plus4: nil, created_at: nil, updated_at:
nil>
>> user.login, user.password, user.email = ''foo'',
''bar'', ''baz''
=> ["foo", "bar", "baz"]
>> user.contact.company_name, user.contact.address.city =
''foobar'', ''foobaz''
=> ["foobar", "foobaz"]
>> user.save
=> true
>> p user, user.contact, user.contact.address
#<User id: 4, login: "foo", first_name: nil, last_name: nil,
email: "baz", password: "bar", contact_id: 2, created_at:
"2009-11-06 02:33:41", updated_at: "2009-11-06 02:33:41">
#<Contact id: 2, company_name: "foobar", address_id: 3,
phone_areacode: nil, phone_prefix: nil, phone_suffix: nil, phone_extension: nil,
website: nil, biztype_id: nil, created_at: "2009-11-06 02:33:41",
updated_at: "2009-11-06 02:33:41">
#<Address id: 3, street_address1: nil, street_address2: nil, city:
"foobaz", state_id: nil, zipcode: nil, plus4: nil, created_at:
"2009-11-06 02:33:41", updated_at: "2009-11-06 02:35:09">
=> nil
As you can see, it appears to work fine, but the following views for
new.html.erb and edit.html.erb don''t:
<h1>New account</h1>
<% form_for(@user) do |f| %>
<%= f.error_messages %>
<p> <%= f.label :login %>: <%= f.text_field :login %>
</p>
<p> <%= f.label :first_name %>: <%= f.text_field :first_name
%> </p>
<p> <%= f.label :last_name %>: <%= f.text_field :last_name
%> </p>
<p> <%= f.label :email %>: <%= f.text_field :email %>
</p>
<p> <%= f.label :password %>: <%= f.password_field :password
%> </p>
<% fields_for(@contact) do |f| %>
<%= f.error_messages %>
<p> <%= f.label :company_name %>: <%= f.text_field
:company_name %> </p>
<p> <%= f.label :Type_of_Organization %>: <%= f.text_field
:biztype_id %> </p>
<% fields_for(@address) do |f| %>
<%= f.error_messages %>
<p> <%= f.label :street_address1 %>: <%= f.text_field
:street_address1 %> </p>
<p> <%= f.label :street_address2 %>: <%= f.text_field
:street_address2 %> </p>
<p> <%= f.label :city %>: <%= f.text_field :city %>
</p>
<p> <%= f.label :state_id %>: <%= f.text_field :state_id,
:maxlength=>2 %> </p>
<p> <%= f.label :zipcode %>: <%= f.text_field :zipcode,
:maxlength=>5 %>-<%= f.text_field :plus4, :maxlength=>4 %>
</p>
<% end %>
<p> <%= f.label :phone %>: (<%= f.text_field
:phone_areacode, :maxlength=>3 %>) <%= f.text_field :phone_prefix,
:maxlength=>3 %>-<%= f.text_field :phone_suffix, :maxlength=>4 %>
Ext. <%= f.text_field :phone_extension, :maxlength=>5 %> </p>
<p> <%= f.label :website %>: <%= f.text_field :website
%> </p>
<% end %>
<p> <%= f.submit ''Create'' %> </p>
<% end %>
<%= link_to ''Back'', accounts_path %>
The view doesn''t create the additional table entries, nor does it allow
me to edit anything but the unjoined data (e.g. @users, not
@users.contact). Obviously I''m still missing something important here.
I
want to be able to both populate *and* edit this content from
similarly-nested views.
Why does this work from the console, but not from within the web app
itself?
--
"Oh, look: rocks!"
-- Doctor Who, "Destiny of the Daleks"