title: Rails Saving Models in Wrong Order
body: <p>i've been searching around for some time now and can't seem to figure out what is causing this, I had a model working saving a volunteer and his home and work addresses. I changed something (cant seem to figure out what for the life of me) and now the address isnt being set.</p>
  
  <p>This is my main model:</p>
  
  <pre><code>class HumanVolunteer &lt; ActiveRecord::Base
  
    has_one :primaryPhone, :class_name =&gt; "PhoneNumber", :foreign_key =&gt; "id", :primary_key =&gt; "phone_id"
    has_one :primaryEmail, :class_name =&gt; "Email", :foreign_key =&gt; "id", :primary_key =&gt; "email_id"
    has_one :work_adr, :class_name =&gt; "Address", :foreign_key =&gt; "id", :primary_key =&gt; "workaddressid"
    has_one :home_adr, :class_name =&gt; "Address", :foreign_key =&gt; "id", :primary_key =&gt; "homeaddressid"
  
    attr_accessible :firstName, :lastName, :homeaddressid, :notes, :status, :workaddressid, :home_adr, :work_adr, 
                :primaryPhone, :primaryEmail, :home_adr_attributes, :work_adr_attributes, :primaryPhone_attributes, 
                :primaryEmail_attributes
  
    accepts_nested_attributes_for :home_adr 
    accepts_nested_attributes_for :work_adr 
    accepts_nested_attributes_for :primaryPhone
    accepts_nested_attributes_for :primaryEmail
  end
  </code></pre>
  
  <p>and the address model:</p>
  
  <pre><code>class Address &lt; ActiveRecord::Base
    attr_accessible :city, :line1, :line2, :notes, :state, :zipcode
    belongs_to :human_volunteer
  end
  </code></pre>
  
  <p>Heres a snippet from the human_volunteers_controller</p>
  
  <pre><code># GET /human_volunteers/new
    # GET /human_volunteers/new.json
    def new
      @human_volunteer = HumanVolunteer.new
      @human_volunteer.build_home_adr
      @human_volunteer.build_work_adr
      @human_volunteer.build_primaryPhone
      @human_volunteer.build_primaryEmail
  
      # Set the Breadcrumbs for this page
      @breadcrumbs = { "Dashboard" =&gt; "/", "Human Volunteers" =&gt; "/human_volunteers"}
      @current_page = "New Volunteer"
  
      respond_to do |format|
        format.html # new.html.erb
        format.json { render :json =&gt; @human_volunteer }
      end
    end
  
    # GET /human_volunteers/1/edit
    def edit
      @human_volunteer = HumanVolunteer.find(params[:id])
      if(@human_volunteer.home_adr.nil?)
        @human_volunteer.build_home_adr
      end
  
      if(@human_volunteer.work_adr.nil?)  
        @human_volunteer.build_work_adr
      end
  
      if(@human_volunteer.primaryPhone.nil?)
        @human_volunteer.build_primaryPhone
      end
  
      if(@human_volunteer.primaryEmail.nil?)
        @human_volunteer.build_primaryEmail
      end
  
      @breadcrumbs = { "Dashboard" =&gt; "/", "Human Volunteers" =&gt; "/human_volunteers"}
      @current_page = "Edit Volunteer: &lt;em&gt;" + @human_volunteer.firstName + " " + @human_volunteer.lastName + "&lt;/em&gt;";
    end
  
    # POST /human_volunteers
    # POST /human_volunteers.json
    def create
      # create the volunteer
      @human_volunteer = HumanVolunteer.new(params[:human_volunteer])
  
      respond_to do |format|
        if @human_volunteer.save
          format.html { redirect_to @human_volunteer, :notice =&gt; @human_volunteer.firstName + ' ' + @human_volunteer.lastName + ' was successfully created.' }
          format.json { render :json =&gt; @human_volunteer, :status =&gt; :created, :location =&gt; @human_volunteer }
        else
          format.html { render :action =&gt; "new" }
          format.json { render :json =&gt; @human_volunteer.errors, :status =&gt; :unprocessable_entity }
        end
      end
    end
  
    # PUT /human_volunteers/1
    # PUT /human_volunteers/1.json
    def update
      @human_volunteer = HumanVolunteer.find(params[:id])
  
      respond_to do |format|
        if @human_volunteer.update_attributes(params[:human_volunteer])
          format.html { redirect_to @human_volunteer, :notice =&gt; @human_volunteer.firstName + ' ' + @human_volunteer.lastName + ' was successfully updated.' }
          format.json { head :no_content }
        else
          format.html { render :action =&gt; "edit" }
          format.json { render :json =&gt; @human_volunteer.errors, :status =&gt; :unprocessable_entity }
        end
      end
    end
  </code></pre>
  
  <p>I can see what i think the problem is by looking at the logs, the human volunteer get saved first, using nulls for the address keys, then the addresses are saved ( also same problem with phone number and email models, they are set up identically to the addresses ) then the addresses are saved, and then the human volunteer is never updated again with the new values:</p>
  
  <pre><code>  Parameters: {"authenticity_token"=&gt;"dD+ut6noFPw8mJHq4rUJpuNBD1o+q0Hi8a+qOeetzMc=", "utf8"=&gt;"✓", "human_volunteer"=&gt;{"lastName"=&gt;"Koch", "work_adr_attributes"=&gt;{"line1"=&gt;"", "line2"=&gt;"", "zipcode"=&gt;"", "state"=&gt;"", "city"=&gt;""}, "primaryEmail_attributes"=&gt;{"email"=&gt;""}, "primaryPhone_attributes"=&gt;{"number"=&gt;""}, "notes"=&gt;"", "home_adr_attributes"=&gt;{"line1"=&gt;"123 Who Knows land", "line2"=&gt;"", "zipcode"=&gt;"11741", "state"=&gt;"TS", "city"=&gt;"testville"}, "firstName"=&gt;"Ken", "status"=&gt;"Investigative Candidate"}}
     (0.2ms)  BEGIN
     (0.2ms)  COMMIT
     (0.2ms)  BEGIN
     (0.1ms)  COMMIT
     (0.1ms)  BEGIN
     (0.1ms)  COMMIT
     (0.1ms)  BEGIN
     (0.1ms)  COMMIT
     (0.1ms)  BEGIN
    SQL (2.3ms)  INSERT INTO "human_volunteers" ("created_at", "email_id", "firstName", "homeaddressid", "lastName", "notes", "phone_id", "status", "updated_at", "workaddressid") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING "id"  [["created_at", Tue, 07 Aug 2012 16:47:16 UTC +00:00], ["email_id", nil], ["firstName", "Ken"], ["homeaddressid", nil], ["lastName", "Koch"], ["notes", ""], ["phone_id", nil], ["status", "Investigative Candidate"], ["updated_at", Tue, 07 Aug 2012 16:47:16 UTC +00:00], ["workaddressid", nil]]
    SQL (0.8ms)  INSERT INTO "phone_numbers" ("created_at", "notes", "number", "phone_id", "phone_type", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"  [["created_at", Tue, 07 Aug 2012 16:47:16 UTC +00:00], ["notes", nil], ["number", ""], ["phone_id", nil], ["phone_type", nil], ["updated_at", Tue, 07 Aug 2012 16:47:16 UTC +00:00]]
    SQL (0.7ms)  INSERT INTO "emails" ("created_at", "email", "notes", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["created_at", Tue, 07 Aug 2012 16:47:16 UTC +00:00], ["email", ""], ["notes", nil], ["updated_at", Tue, 07 Aug 2012 16:47:16 UTC +00:00]]
    SQL (0.9ms)  INSERT INTO "addresses" ("city", "created_at", "line1", "line2", "notes", "state", "updated_at", "zipcode") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"  [["city", ""], ["created_at", Tue, 07 Aug 2012 16:47:16 UTC +00:00], ["line1", ""], ["line2", ""], ["notes", nil], ["state", ""], ["updated_at", Tue, 07 Aug 2012 16:47:16 UTC +00:00], ["zipcode", nil]]
    SQL (0.5ms)  INSERT INTO "addresses" ("city", "created_at", "line1", "line2", "notes", "state", "updated_at", "zipcode") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"  [["city", "testville"], ["created_at", Tue, 07 Aug 2012 16:47:16 UTC +00:00], ["line1", "123 Who Knows land"], ["line2", ""], ["notes", nil], ["state", "TS"], ["updated_at", Tue, 07 Aug 2012 16:47:16 UTC +00:00], ["zipcode", 11741]]
    (17.8ms)  COMMIT
  </code></pre>
  
  <p>EDIT: If this is any help here is an example of the old entry in the log:</p>
  
  <pre><code>Started POST "/human_volunteers" for 127.0.0.1 at Sat Jul 28 09:08:59 -0400 2012
  Processing by HumanVolunteersController#create as HTML
    Parameters: {"human_volunteer"=&gt;{"firstName"=&gt;"Ken", "work_adr"=&gt;{"city"=&gt;"", "state"=&gt;"", "zipcode"=&gt;"", "line1"=&gt;"", "line2"=&gt;""}, "status"=&gt;"Trainee", "home_adr"=&gt;{"city"=&gt;"fdsa", "state"=&gt;"Nasdf", "zipcode"=&gt;"11729", "line1"=&gt;"asdf fdsafd", "line2"=&gt;""}, "primaryEmail"=&gt;"ken.koch@essencedesigns.net", "primaryPhone"=&gt;"6316813806", "lastName"=&gt;"Koch", "notes"=&gt;"\r\nHes a good guy"}, "authenticity_token"=&gt;"bgbecE+nMxNrPtleNOLfO/MqRib0cXmDMqL5JaPyC10=", "utf8"=&gt;"✓"}
    [1m[36m (0.1ms)[0m  [1mBEGIN[0m
    [1m[35mSQL (0.5ms)[0m  INSERT INTO "emails" ("created_at", "email", "notes", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["created_at", Sat, 28 Jul 2012 13:08:59 UTC +00:00], ["email", "ken.koch@essencedesigns.net"], ["notes", nil], ["updated_at", Sat, 28 Jul 2012 13:08:59 UTC +00:00]]
    [1m[36m (19.1ms)[0m  [1mCOMMIT[0m
    [1m[35m (0.1ms)[0m  BEGIN
    [1m[36mSQL (0.5ms)[0m  [1mINSERT INTO "phone_numbers" ("created_at", "notes", "number", "phone_id", "phone_type", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"[0m  [["created_at", Sat, 28 Jul 2012 13:08:59 UTC +00:00], ["notes", nil], ["number", "6316813806"], ["phone_id", nil], ["phone_type", nil], ["updated_at", Sat, 28 Jul 2012 13:08:59 UTC +00:00]]
    [1m[35m (56.9ms)[0m  COMMIT
    [1m[36m (0.1ms)[0m  [1mBEGIN[0m
    [1m[35mSQL (2.5ms)[0m  INSERT INTO "addresses" ("city", "created_at", "line1", "line2", "notes", "state", "updated_at", "zipcode") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"  [["city", ""], ["created_at", Sat, 28 Jul 2012 13:08:59 UTC +00:00], ["line1", ""], ["line2", ""], ["notes", nil], ["state", ""], ["updated_at", Sat, 28 Jul 2012 13:08:59 UTC +00:00], ["zipcode", nil]]
    [1m[36m (9.4ms)[0m  [1mCOMMIT[0m
    [1m[35m (0.1ms)[0m  BEGIN
    [1m[36mSQL (0.5ms)[0m  [1mINSERT INTO "addresses" ("city", "created_at", "line1", "line2", "notes", "state", "updated_at", "zipcode") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"[0m  [["city", "Deer Park"], ["created_at", Sat, 28 Jul 2012 13:08:59 UTC +00:00], ["line1", "294 West 15th St"], ["line2", ""], ["notes", nil], ["state", "NY"], ["updated_at", Sat, 28 Jul 2012 13:08:59 UTC +00:00], ["zipcode", 11729]]
    [1m[35m (7.0ms)[0m  COMMIT
    [1m[36m (0.1ms)[0m  [1mBEGIN[0m
    [1m[35mSQL (1.1ms)[0m  INSERT INTO "human_volunteers" ("created_at", "email_id", "firstName", "homeaddressid", "lastName", "notes", "phone_id", "status", "updated_at", "workaddressid") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING "id"  [["created_at", Sat, 28 Jul 2012 13:08:59 UTC +00:00], ["email_id", 5], ["firstName", "Ken"], ["homeaddressid", 14], ["lastName", "Koch"], ["notes", "\r\nHes a good guy"], ["phone_id", 11], ["status", "Trainee"], ["updated_at", Sat, 28 Jul 2012 13:08:59 UTC +00:00], ["workaddressid", 13]]
    [1m[36m (6.1ms)[0m  [1mCOMMIT[0m
  Redirected to http://localhost:3000/human_volunteers/1
  Completed 302 Found in 178ms (ActiveRecord: 112.1ms)
  </code></pre>
  
  <p>I was able to look back into the log and find one that worked, and the human_volunteer was the last thing inserted. It inserted addresses, emails, phones first, then used those id's when inserting the volunteer.</p>
  
  <p>EDIT: I can also report that I am not getting any errors, everything goes through, just the data isnt connected.</p>
  
  <p>Any ideas what could cause the change in the order? I can't see that  i changed anything that affected this.</p>
  
  <p>UPDATE: I tried changing the has_one lines and was able to at least produce an error (for better or worse), when i cahnged the lines to:</p>
  
  <pre><code>  has_one :workaddress, :class_name =&gt; "Address", :foreign_key =&gt; "id", :primary_key =&gt; "workaddress"
    has_one :homeaddress, :class_name =&gt; "Address", :foreign_key =&gt; "id", :primary_key =&gt; "homeaddress"
  </code></pre>
  
  <p>It tries to use the addressid 1 everytime and i get </p>
  
  <pre><code>ActiveRecord::RecordNotUnique (PG::Error: ERROR:  duplicate key value violates unique constraint "addresses_pkey"
  DETAIL:  Key (id)=(1) already exists.
  </code></pre>
  
  <p>Also if i take out the primary_key field, it seems to work, but it tries to set them both to the same address and i get the same error except with the next id (22, 23, 24 etc each time i try it)</p>
  
  <p>Maybe that sheds some light on the problem? I'm going to keep prodding around.</p>
  
  <p>Thank you very much, 
  - Ken</p>