25

我有一个简单的模型:

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

在我的控制器中,我有一个简单的更新方法:

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

这不会引发错误,但实际上也不会更新回复。相反,我得到“我正在尝试更新!” 消息,就像一切正常。但是当我重新加载页面并查看回复时,它具有相同的文本。它实际上并没有更新。如果我将 update_attributes 替换为:

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

它工作正常。如果我使用:

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

它再次不起作用。知道发生了什么吗?

在我的日志中,我有这个:

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)
4

3 回答 3

83

您使用的三种方法做不同的事情:

  • update_attributes尝试验证记录,调用回调保存
  • update_attribute不验证记录,调用回调保存
  • update_column不验证记录,不调用回调,不调用保存方法,尽管它确实更新了数据库中的记录。

如果我猜唯一“有效”的方法update_column是你在某个地方有一个抛出错误的回调。尝试检查您的log/development.log文件以了解发生了什么。

您也可以使用update_attributes!. 此变体将引发错误,因此它可能会为您提供有关模型未保存的原因的信息。

update_attributes除非您确切知道自己在做什么,否则您应该使用并避免使用其他两种方法。如果您稍后在模型中添加验证和回调,使用update_attributeandupdate_column可能会导致非常难以调试的令人讨厌的行为。

您可以查看此链接以获取更多信息。

于 2013-01-19T16:42:06.943 回答
0

一个直觉的猜测是说你有一个质量分配问题,应该像这样在你的模型中添加你的属性

attr_accessible: :your_attribute, :your_attribute2
于 2013-01-24T15:50:47.850 回答
0

我遇到了同样的问题,但是使用 Rails 4。当您在 update_attribute 中有 params[] 时,就会出现问题。在具有强参数的 Rails 4 中

@reply.update_attributes(params[reply_params])

应该

@reply.update_attributes(reply_params)

我不熟悉 Rails 3,但这应该是问题所在:

@reply.update_attributes(params[:reply])

应该

@reply.update_attributes(:reply)
于 2014-04-30T03:34:08.423 回答