title: Rails 4: can't update polymorphic nested resource through form
body: <p>Just in the final stages of transferring an app stuck in Rails 2 on a shared server to Rails 4 on a VPS, but stuck on one thing.</p>
  
  <p>I have an Image model that uses Carrierwave to upload and display attached images. The Image model has a polymorphic association to a couple of other models. The host and associated models are updated together on a combined multipart form.</p>
  
  <p>The form works perfectly well for creating and editing the primary model and for creating and attaching new images, but the image attributes can't be edited, and no error is thrown to help.</p>
  
  <p>Here are the relevant parts of my Image model:</p>
  
  <pre><code>class Image &lt; ActiveRecord::Base
    belongs_to :imagings, polymorphic: true, touch: true
    mount_uploader :image, ImageUploader, mount_on: :image_file_name
  end
  </code></pre>
  
  <p>And my Review model:</p>
  
  <pre><code>class Review &lt; ActiveRecord::Base
    has_many :images, as: :imagings, dependent: :destroy  
    accepts_nested_attributes_for :images, reject_if: lambda { |t| t['image'].nil? }, allow_destroy: true
  end
  </code></pre>
  
  <p>And my Reviews Controller:</p>
  
  <pre><code>class ReviewsController &lt; ApplicationController
    def edit
      @review = Review.find(params[:id])
      3.times {@review.images.build}
    end
  
    def update
      @review = Review.find(params[:id])
      if @review.update(reviews_params)
        redirect_to @review, notice: "Successfully updated review."
      else
        render :edit
      end
    end
  
    private
  
    def reviews_params
     params.require(:review).permit(:title, :authors, :venue, :startdate, :enddate, :body, :approved, :company, :user_id, { images_attributes: [:title, :credits, :image, :_destroy, :id] })
    end
  end
  </code></pre>
  
  <p>I can add images to existing reviews or to a new review perfectly well with this setup, but if I try to change text fields for an existing image, the parameters show in the console but they are ignored:</p>
  
  <pre><code>Started PATCH "/reviews/492" for 127.0.0.1 at 2014-07-16 11:03:42 +0100
  Processing by ReviewsController#update as HTML
    Parameters: {"utf8"=&gt;"✓", "authenticity_token"=&gt;"HvrsCAXXvO4zIqTBw05qSUwU9I2241DXyilhswEbU9o=", "review"=&gt;{"title"=&gt;"Here's a new review", "authors"=&gt;"", "company"=&gt;"", "venue"=&gt;"", "startdate"=&gt;"2014-07-16", "enddate"=&gt;"2014-07-31", "body"=&gt;"&lt;p&gt;Something&lt;/p&gt;", "images_attributes"=&gt;{"0"=&gt;{"title"=&gt;"Doggie", "credits"=&gt;"Icons galore", "_destroy"=&gt;"0", "id"=&gt;"1239"}, "1"=&gt;{"title"=&gt;"", "credits"=&gt;""}, "2"=&gt;{"title"=&gt;"", "credits"=&gt;""}, "3"=&gt;{"title"=&gt;"", "credits"=&gt;""}}, "user_id"=&gt;"4", "approved"=&gt;"1"}, "commit"=&gt;"Update Review", "id"=&gt;"492"}
    User Load (0.4ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
    Review Load (0.3ms)  SELECT  "reviews".* FROM "reviews"  WHERE "reviews"."id" = $1 LIMIT 1  [["id", 492]]
     (12.4ms)  BEGIN
    Image Load (0.4ms)  SELECT "images".* FROM "images"  WHERE "images"."imagings_id" = $1 AND "images"."imagings_type" = $2 AND "images"."id" IN (1239)  [["imagings_id", 492], ["imagings_type", "Review"]]
     (0.2ms)  COMMIT
  Redirected to http://127.0.0.1:3000/reviews/492
  Completed 302 Found in 27ms (ActiveRecord: 13.6ms)
  </code></pre>
  
  <p>You can see here how the images attribute for credit has the change to "Icons galore", but the SQL only fetches the linked image without updating it. Contrast this with the following update to the main model which does a select followed by an update between the BEGIN and COMMIT.</p>
  
  <pre><code>Started PATCH "/reviews/492" for 127.0.0.1 at 2014-07-16 11:26:01 +0100
  Processing by ReviewsController#update as HTML
    Parameters: {"utf8"=&gt;"✓", "authenticity_token"=&gt;"HvrsCAXXvO4zIqTBw05qSUwU9I2241DXyilhswEbU9o=", "review"=&gt;{"title"=&gt;"Here's a new review", "authors"=&gt;"", "company"=&gt;"", "venue"=&gt;"", "startdate"=&gt;"2014-07-16", "enddate"=&gt;"2014-07-31", "body"=&gt;"&lt;p&gt;Something else&lt;/p&gt;", "images_attributes"=&gt;{"0"=&gt;{"title"=&gt;"Doggie", "credits"=&gt;"Icons", "_destroy"=&gt;"0", "id"=&gt;"1239"}, "1"=&gt;{"title"=&gt;"", "credits"=&gt;""}, "2"=&gt;{"title"=&gt;"", "credits"=&gt;""}, "3"=&gt;{"title"=&gt;"", "credits"=&gt;""}}, "user_id"=&gt;"4", "approved"=&gt;"1"}, "commit"=&gt;"Update Review", "id"=&gt;"492"}
    User Load (6.4ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
    Review Load (0.3ms)  SELECT  "reviews".* FROM "reviews"  WHERE "reviews"."id" = $1 LIMIT 1  [["id", 492]]
     (18.1ms)  BEGIN
    Image Load (0.5ms)  SELECT "images".* FROM "images"  WHERE "images"."imagings_id" = $1 AND "images"."imagings_type" = $2 AND "images"."id" IN (1239)  [["imagings_id", 492], ["imagings_type", "Review"]]
    SQL (5.9ms)  UPDATE "reviews" SET "body" = $1, "updated_at" = $2 WHERE "reviews"."id" = 492  [["body", "&lt;p&gt;Something else&lt;/p&gt;"], ["updated_at", "2014-07-16 10:26:01.455481"]]
     (24.8ms)  COMMIT
  Redirected to http://127.0.0.1:3000/reviews/492
  Completed 302 Found in 120ms (ActiveRecord: 56.0ms)
  </code></pre>
  
  <p>Yet if I try to make the same update in the Rails console, it sometimes works perfectly:</p>
  
  <pre><code>2.1.1 :062 &gt; review =  Review.find(492)
    Review Load (0.5ms)  SELECT  "reviews".* FROM "reviews"  WHERE "reviews"."id" = $1 LIMIT 1  [["id", 492]]
   =&gt; #&lt;Review id: 492, title: "Here's a new review", authors: "", venue: "", startdate: "2014-07-16", enddate: "2014-07-31", body: "&lt;p&gt;Something else&lt;/p&gt;", approved: true, created_at: "2014-07-16 09:38:33", updated_at: "2014-07-16 10:26:01", user_id: 4, company: ""&gt; 
  2.1.1 :064 &gt; review.images.first.title = "Doggies galore"
   =&gt; "Doggies galore" 
  2.1.1 :066 &gt; review.save
     (0.8ms)  BEGIN
    SQL (7.5ms)  UPDATE "images" SET "title" = $1, "updated_at" = $2 WHERE "images"."id" = 1239  [["title", "Doggies galore"], ["updated_at", "2014-07-16 10:32:39.109784"]]
    Review Load (0.3ms)  SELECT  "reviews".* FROM "reviews"  WHERE "reviews"."id" = $1 LIMIT 1  [["id", 492]]
    SQL (1.7ms)  UPDATE "reviews" SET "updated_at" = '2014-07-16 10:32:39.129314' WHERE "reviews"."id" = 492
     (1.6ms)  COMMIT
   =&gt; true
  </code></pre>
  
  <p>And sometimes doesn't:</p>
  
  <pre><code>2.1.1 :082 &gt; review =  Review.find(492)
    Review Load (0.3ms)  SELECT  "reviews".* FROM "reviews"  WHERE "reviews"."id" = $1 LIMIT 1  [["id", 492]]
   =&gt; #&lt;Review id: 492, title: "Here's a new review", authors: "", venue: "", startdate: "2014-07-16", enddate: "2014-07-31", body: "&lt;p&gt;Something else&lt;/p&gt;", approved: true, created_at: "2014-07-16 09:38:33", updated_at: "2014-07-16 10:38:30", user_id: 4, company: ""&gt; 
  2.1.1 :083 &gt; review.images.first.credits = "Icons galore"
    Image Load (0.5ms)  SELECT  "images".* FROM "images"  WHERE "images"."imagings_id" = $1 AND "images"."imagings_type" = $2  ORDER BY "images"."id" ASC LIMIT 1  [["imagings_id", 492], ["imagings_type", "Review"]]
   =&gt; "Icons galore" 
  2.1.1 :084 &gt; review.save!
     (0.2ms)  BEGIN
     (0.3ms)  COMMIT
   =&gt; true 
  2.1.1 :085 &gt; review.images.first
    Image Load (0.8ms)  SELECT  "images".* FROM "images"  WHERE "images"."imagings_id" = $1 AND "images"."imagings_type" = $2  ORDER BY "images"."id" ASC LIMIT 1  [["imagings_id", 492], ["imagings_type", "Review"]]
   =&gt; #&lt;Image id: 1239, title: "Doggies", credits: "Icons", created_at: "2014-07-16 09:38:33", updated_at: "2014-07-16 10:38:30", image_file_name: "ddad7b05-3430-49ed-b129-fd484ac793ad.gif", image_content_type: nil, image_file_size: nil, image_updated_at: nil, imagings_id: 492, imagings_type: "Review", original_filename: "Doggie.gif"&gt; 
  2.1.1 :086 &gt; 
  </code></pre>
  
  <p>I know I'm missing something obvious. Can anyone help please?</p>