Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: update_column works, but not update_attributes

I have a simple model:

class Reply < ActiveRecord::Base
  attr_accessible :body
  belongs_to :post
end

In my controller, I have a simple update method:

def update
  @reply = Reply.find(params[:id])
  if @reply.update_attributes!(params[:reply])
    render :js => "alert('I am trying to update!')"
  else
    render :js => "alert('<%= @reply.errors %>')"
  end
end

This doesn't throw an error, but neither does it actually update the reply. Instead, I get the "I am trying to update!" message, like everything worked. But when I reload the page and look at the reply, it has the same text. It hasn't actually been updated. If I replace update_attributes with:

@reply.update_column(:body, params[:reply][:body])

It works fine. If I use:

@reply.update_attribute(:body, params[:reply][:body])

It once again doesn't work. Any idea what's going?

In my log, I have this:

Started PUT "/posts/2/replies/20" for 127.0.0.1 at 2013-01-19 10:39:57 -0600
Processing by RepliesController#update as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Xot7E+ldXiBm0hVvw5XUP/U5guJU2g8e4QaLbDVGzDE=", "reply"=>{"body"=>"Updated text."}, "commit"=>"Submit Revision", "post_id"=>"2", "id"=>"20"
[1m[35mUser Load (1.0ms)[0m  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
[1m[36mReply Load (0.0ms)[0m  [1mSELECT `replies`.* FROM `replies` WHERE `replies`.`id` = 20 LIMIT 1[0m
[1m[35m (1.0ms)[0m  BEGIN
[1m[36mPost Load (0.0ms)[0m  [1mSELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 2 LIMIT 1[0m
[1m[35m (0.0ms)[0m  COMMIT
Rendered replies/_reply_content.html.erb (502.0ms)
Rendered replies/update.js.erb (505.0ms)
Completed 200 OK in 849ms (Views: 484.0ms | ActiveRecord: 94.0ms)
like image 980
nullnullnull Avatar asked Sep 06 '25 03:09

nullnullnull


1 Answers

The three methods you are using do different things:

  • update_attributes tries to validate the record, calls callbacks and saves;
  • update_attribute doesn't validate the record, calls callbacks and saves;
  • update_column doesn't validate the record, doesn't call callbacks, doesn't call save method, though it does update record in the database.

If the only method that "works" is update_column my guess is that you have a callback somewhere that is throwing an error. Try to check your log/development.log file to see what's going on.

You can also use update_attributes!. This variant will throw an error, so it may give you information on why your model isn't saving.

You should use update_attributes and avoid the two other methods unless you know exactly what you are doing. If you add validations and callbacks later to your model, using update_attribute and update_column can lead to nasty behaviour that is really difficult to debug.

You can check this link for more info on that.

like image 199
alestanis Avatar answered Sep 09 '25 23:09

alestanis