title: Rails 4 update nested models using accepts_nested_attributes_for
body: <p>I'm trying to get a Rails 4 based api (not using views/forms) to accept a json object graph and update all of the associated models. I wasn't having any luck on the main project so I created a basic project to try to get it to work and I cannot get Rails to allow the elements in the json data for the nested models to be "permitted" parameters.</p>
  
  <p>I have three models: Top, Middle and Bottom. Top has many Middles and Middle has many Bottoms. Everyting is setup in the database and I have a TopsController that I'm using to receive the PUT:</p>
  
  <p><strong>app/controllers/api/tops_controller.rb:</strong></p>
  
  <pre><code>class Api::TopsController &lt; ApplicationController
  
    respond_to :json
  
    def show
      all = Top.all
      render json: { result: "success", tops: all }
    end
  
    def update
      top = Top.find(params[:top][:id])
      top.update(top_params)
      render json: { result: "updated", top: top }
    end
  
  
    private
  
    def top_params
      params.require(:top).permit(:name, :middles_attributes =&gt; [:id, :name])
    end
  
  end
  </code></pre>
  
  <p><strong>app/models/top.rb:</strong></p>
  
  <pre><code>class Top &lt; ActiveRecord::Base
    has_many :middles
    accepts_nested_attributes_for :middles, allow_destroy: true, reject_if: :all_blank
  
    def as_json(options = {})
      attrs = self.attributes
      attrs['middles'] = self.middles
      attrs
    end
  
  end
  </code></pre>
  
  <p><strong>app/models/middle.rb:</strong></p>
  
  <pre><code>class Middle &lt; ActiveRecord::Base
    belongs_to :top
    has_many :bottoms
    accepts_nested_attributes_for :bottoms, allow_destroy: true, reject_if: :all_blank
  
    def as_json(options = {})
      attrs = self.attributes
      attrs['bottoms'] = self.bottoms
      attrs
    end
  end
  </code></pre>
  
  <p><strong>app/models/bottom.rb:</strong></p>
  
  <pre><code>class Bottom &lt; ActiveRecord::Base
    belongs_to :middle
  end
  </code></pre>
  
  <p>This is the update.json file I'm cURLing to the server:</p>
  
  <pre><code>{
      "top":{
          "id":1,
          "name":"NewTopName",
          "middles":[
              {
                  "id":1,
                  "name":"UpdatedMiddleName",
                  "top_id":1,
                  "bottoms":[
                      {
                          "id":1,
                          "name":"UpdatedBottomName",
                          "middle_id":1
                      }
                  ]
              }
          ]
      }
  }
  </code></pre>
  
  <p>I cURL it using:</p>
  
  <pre><code>curl -X PUT -H "Content-Type: application/json" --data @update.json  http://localhost:3000/top/edit
  </code></pre>
  
  <p>The Top.name property is updated every time, no problem, but the Middle and Bottom data is ignored. Looking at the server output I see this:</p>
  
  <pre><code>Started PUT "/top/edit" for 127.0.0.1 at 2014-10-09 17:09:24 -0700
  Processing by Api::TopsController#update as JSON
    Parameters: {"top"=&gt;{"id"=&gt;1, "name"=&gt;"NewTopName", "middles"=&gt;[{"id"=&gt;1, "name"=&gt;"UpdatedMiddleName", "top_id"=&gt;1, "bottoms"=&gt;[{"id"=&gt;1, "name"=&gt;"UpdatedBottomName", "middle_id"=&gt;1}]}]}}
    Top Load (0.2ms)  SELECT  "tops".* FROM "tops"  WHERE "tops"."id" = $1 LIMIT 1  [["id", 1]]
  Unpermitted parameters: id, middles
  ...
  </code></pre>
  
  <p>The <code>Unpermitted parameters: id, middles</code> part seems to be telling me that it can't(won't) process those middles parameters in the update, even though I've permitted them in the TopsController::top_params method using <code>:middles_attributes =&gt; [:id, :name]</code> (and a few other ways, including <code>... :middles =&gt; []</code>).</p>
  
  <p>I'm clearly missing something here, but I cannot for the life of me see what it is. Any suggestions? Thanks! </p>