How do I use accepts_nested_attributes_for?

Posted by Angela on Stack Overflow See other posts from Stack Overflow or by Angela
Published on 2010-05-09T03:19:03Z Indexed on 2010/05/14 1:44 UTC
Read the original article Hit count: 301

Editing my question for conciseness and to update what I've done:

How do I model having multiple Addresses for a Company and assign a single Address to a Contact, and be able to assign them when creating or editing a Contact?

I want to use nested attributes to be able to add an address at the time of creating a new contact. That address exists as its own model because I may want the option to drop-down from existing addresses rather than entering from scratch.

I can't seem to get it to work. I get a undefined method `build' for nil:NilClass error

Here is my model for Contacts:

class Contact < ActiveRecord::Base
  attr_accessible :first_name, :last_name, :title, :phone, :fax, :email, :company, 
                  :date_entered, :campaign_id, :company_name, :address_id, :address_attributes

  belongs_to :company
  belongs_to :address
  accepts_nested_attributes_for :address
end

Here is my model for Address:

class Address < ActiveRecord::Base
  attr_accessible :street1, :street2, :city, :state, :zip

  has_many :contacts
end

I would like, when creating an new contact, access all the Addresses that belong to the other Contacts that belong to the Company. So here is how I represent Company:

class Company < ActiveRecord::Base
  attr_accessible :name, :phone, :addresses

  has_many :contacts

  has_many :addresses, :through => :contacts

end

Here is how I am trying to create a field in the View for _form for Contact so that, when someone creates a new Contact, they pass the address to the Address model and associate that address to the Contact:

  <% f.fields_for :address, @contact.address do |builder| %>
  <p>
    <%= builder.label :street1, "Street 1" %> </br> 
    <%= builder.text_field :street1 %>
  <p>
  <% end %>

When I try to Edit, the field for Street 1 is blank. And I don't know how to display the value from show.html.erb.

At the bottom is my error console -- can't seem to create values in the address table:

My Contacts controller is as follows:

  def new
    @contact = Contact.new
    @contact.address.build # Iundefined method `build' for nil:NilClass

    @contact.date_entered = Date.today
    @campaigns = Campaign.find(:all, :order => "name")
    if params[:campaign_id].blank? 

    else
      @campaign = Campaign.find(params[:campaign_id])
      @contact.campaign_id = @campaign.id
    end

    if params[:company_id].blank?

    else
      @company = Company.find(params[:company_id])
      @contact.company_name = @company.name
    end

  end

  def create
    @contact = Contact.new(params[:contact])
    if @contact.save
      flash[:notice] = "Successfully created contact."
      redirect_to @contact
    else
      render :action => 'new'
    end
  end

  def edit
    @contact = Contact.find(params[:id])
    @campaigns = Campaign.find(:all, :order => "name")
  end

Here is a snippet of my error console: I am POSTING the attribute, but it is not CREATING in the Address table....

Processing ContactsController#create (for 127.0.0.1 at 2010-05-12 21:16:17)

[POST] Parameters: {"commit"=>"Submit", "authenticity_token"=>"d8/gx0zy0Vgg6ghfcbAYL0YtGjYIUC2b1aG+dDKjuSs=", "contact"=>{"company_name"=>"Allyforce", "title"=>"", "campaign_id"=>"2", "address_attributes"=>{"street1"=>"abc"}, "fax"=>"", "phone"=>"", "last_name"=>"", "date_entered"=>"2010-05-12", "email"=>"", "first_name"=>"abc"}}

Company Load (0.0ms)[0m [0mSELECT * FROM "companies" WHERE ("companies"."name" = 'Allyforce') LIMIT 1[0m

Address Create (16.0ms)[0m
[0;1mINSERT INTO "addresses" ("city", "zip", "created_at", "street1", "updated_at", "street2", "state") VALUES(NULL, NULL, '2010-05-13 04:16:18', NULL, '2010-05-13 04:16:18', NULL, NULL)[0m

Contact Create (0.0ms)[0m
[0mINSERT INTO "contacts" ("company", "created_at", "title", "updated_at", "campaign_id", "address_id", "last_name", "phone", "fax", "company_id", "date_entered", "first_name", "email") VALUES(NULL, '2010-05-13 04:16:18', '', '2010-05-13 04:16:18', 2, 2, '', '', '', 5, '2010-05-12', 'abc', '')[0m

© Stack Overflow or respective owner

Related posts about has-many-through

    Related posts about aggregation