title: Ajax is updating all attributes on a cropped image, therefore reprocessing the image without the cropped dimensions
body: <p>I'm cropping images with carrierwave and Jcrop. The model that holds the image is called <code>Item</code> and the field that stores the image is called <code>cover</code>.</p>
  
  <p>The cropping is working well. The problem is to do with an ajax action for voting for the item.</p>
  
  <p>Each item has a field called <code>votes</code>. I have a button on top of the item that when clicked adds 1 to the <code>votes</code> value by increment. If I don't use the ajax action, it updates the record correctly, no harm done. However, if I use the ajax action it updates all of the fields in the Item record with new attributes, attributes that change the dimensions of the cropped image to almost zero, which then triggers the after_update callback that reprocesses the image.</p>
  
  <p>The result is that I get an image that is 1px by 1px and completely white.</p>
  
  <p>How can I change my ajax action to that this doesn't happen?</p>
  
  <p>Thanks</p>
  
  <pre><code>  def vote
      item = Item.find(params[:item_id])
      item.increment!(:votes)
  
      if request.xhr?
        render json: {votes: item.votes}
      else
        redirect_to users_url
      end
    end
  
  jQuery ($) -&gt;
    $('form.vote').submit (evt) -&gt;
      evt.preventDefault()
  
      $form = $ @
      $form.find(':submit').prop 'disabled', true
      $.post($form.attr('action'), $form.serializeArray(), type: 'json').done (data) -&gt;
        $form.parent().find(".vote_count").text data.votes
  </code></pre>
  
  <p>And for reference the Item model:</p>
  
  <pre><code>class Item &lt; ActiveRecord::Base
    before_create :update_image_attributes
    before_update :reprocess_image, :if =&gt; :cropping?
  
    belongs_to :user
  
    attr_accessible :available, :cover, :privacy, :size, :title, :votes, :user_id, :description, :crop_x, :crop_y, :crop_w, :crop_h
  
    mount_uploader :cover, CoverUploader
  
    def cropping?
      !crop_x.blank? &amp;&amp; !crop_y.blank? &amp;&amp; !crop_w.blank? &amp;&amp; !crop_h.blank?
    end
  
    private
  
    def update_image_attributes
      if cover.present?
        self.content_type = cover.file.content_type
        self.file_size = cover.file.size
        self.width, self.height = `identify -format "%wx%h" #{cover.file.path}`.split(/x/)
      end
    end
  
    def reprocess_image
        cover.reprocess(crop_x, crop_y, crop_w, crop_h)
        cover.cache_stored_file!
    end
  
  end
  </code></pre>
  
  <p>And Controller</p>
  
  <pre><code>class ItemsController &lt; ApplicationController
        before_filter :authenticate
  
        def crop
          @item = Item.find(params[:image_id])
          @user = User.find(params[:user_id])
          respond_to do |format|
            if @item.update_attributes(:crop_x =&gt; params[:crop_x],:crop_y =&gt; params[:crop_y],:crop_w =&gt; params[:crop_w],:crop_h =&gt; params[:crop_h])
              format.html { redirect_to items_url }
              format.js
            else
              redirect_to root_url
            end
          end
        end
  
        # GET /items
        # GET /items.json
        def index
          @items = Item.all
  
          respond_to do |format|
            format.html # index.html.erb
            format.json { render json: @items }
          end
        end
  
        # GET /items/1
        # GET /items/1.json
        def show
          @item = Item.find(params[:id])
  
          respond_to do |format|
            format.html # show.html.erb
            format.json { render json: @item }
          end
        end
  
        # GET /items/new
        # GET /items/new.json
        def new
          @item = Item.new
  
          respond_to do |format|
            format.html # new.html.erb
            format.json { render json: @item }
          end
        end
  
        # GET /items/1/edit
        def edit
          @item = Item.find(params[:id])
        end
  
        # POST /items
        # POST /items.json
        def create
          @item = Item.create(params[:item])
          respond_to do |format|
            if @item.save
              format.html { redirect_to items_url }
              format.js
            else
              format.html { render action: "new" }
              format.json { render json: @item.errors, status: :unprocessable_entity }
            end
          end
        end
  
        # PUT /items/1
        # PUT /items/1.json
        def update
          @item = Item.find(params[:id])
          respond_to do |format|
            if @item.update_attributes(params[:item])
              format.html { redirect_to @item, notice: 'Item was successfully updated.' }
              format.json { head :no_content }
            else
              format.html { render action: "edit" }
              format.json { render json: @item.errors, status: :unprocessable_entity }
            end
          end
        end
  
        # DELETE /items/1
        # DELETE /items/1.json
        def destroy
          @item = Item.find(params[:id])
          @item.destroy
  
          respond_to do |format|
            format.html { redirect_to items_url }
            format.json { head :no_content }
          end
        end
  
        private
  
        def authenticate
          if current_user.nil?
            redirect_to root_path, :alert =&gt; "You must first log in to access this page"
          end
        end
      end
  </code></pre>
  
  <p>Update - log of the commit </p>
  
  <pre><code>Started POST "/vote" for 127.0.0.1 at 2012-08-15 23:28:03 +0200
  Processing by VotesController#vote as */*
    Parameters: {"utf8"=&gt;"✓", "authenticity_token"=&gt;"uVxsVGsXImC2VPsavIjZfIUMnGmlyjYEmubI8oODgdk=", "item_id"=&gt;"107", "user_id"=&gt;"1"}
    Category Load (0.2ms)  SELECT "categories".* FROM "categories" 
    Color Load (0.1ms)  SELECT "colors".* FROM "colors" 
    User Load (0.1ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", "1"]]
     (0.1ms)  begin transaction
    SQL (9.2ms)  INSERT INTO "votes" ("created_at", "item_id", "updated_at", "user_id") VALUES (?, ?, ?, ?)  [["created_at", Wed, 15 Aug 2012 21:28:03 UTC +00:00], ["item_id", 107], ["updated_at", Wed, 15 Aug 2012 21:28:03 UTC +00:00], ["user_id", 1]]
     (3.1ms)  commit transaction
    Item Load (0.3ms)  SELECT "items".* FROM "items" WHERE "items"."id" = ? LIMIT 1  [["id", 107]]
     (0.0ms)  begin transaction
     (0.4ms)  UPDATE "items" SET "votes" = 1, "updated_at" = '2012-08-15 21:28:03.656131' WHERE "items"."id" = 107
     (23.2ms)  commit transaction
  </code></pre>