无法使用ActiveRecord更新属性

时间:2011-11-15 02:48:29

标签: mysql ruby activerecord orm

我想将answers表中的内容与ActiveRecord交换 代码1:

Archieve::Answer.find_each do |answer|
  str = answer.content
  dosomething() #change the value
  answer.update_attribute(:content,str)
end

但它不会改变内容的价值。

代码2:

Archieve::Answer.find_each do |answer|
  str = answer.content
  dosomething() #change the value
  answer.reload
  answer.update_attributes(
    :content => str
  )
end

在更新:content属性之前,我每次都会reload。{ 它确实可以改变价值 为什么呢?
code 1&之间有什么区别? code 2
Source Code

###1 Post Debug Message:
Updated Post:

Changed?: false 
valid?: true 
errors: #<ActiveModel::Errors:0xa687568> 
errors: #<ActiveModel::Errors:0xa687568 @base=#<Archieve::Answer id: 9997190932758339, user_id: 4163690810052834, question_id: 3393286738785869, content: "狗狗生病,好可怜呀,", is_correct: false, votes_count: 0, comments_count: 0, created_at: "2011-11-06 18:38:53", updated_at: "2011-11-06 18:38:53">, @messages={}>

1 个答案:

答案 0 :(得分:0)

可能的ActiveRecord 3.1.1错误

OP向我提到他在一个独立的脚本中使用require "active_record"(不使用rails runner)。 他的任务没有单独的Rails应用程序,他只使用脚本。这不一定是坏的,并且在早期的ActiveRecord版本中有效,例如2.x AFAIK - 由于新的依赖性,这可能是Rails 3.1中的回归?

# the OP's require statements:
require 'rubygems'
require 'logger'
require 'yaml'
require 'uuidtools'
require 'active_record'

此处填写完整代码:https://raw.github.com/Zhengquan/Swap_Chars/master/lib/orm.rb

可能缺少依赖关系,或者AR 3.1.1在初始化时独立存在问题?

实际上可能是一个错误

可能是update_attribute()触发了属性的脏跟踪中的错误,然后错误地假设对象没有改变,因此它不会被持久化,尽管{{1}的实现1}}调用update_attribute()(请参阅下面的代码片段)。

我在Mongoid的旧版本中看到过类似的内容 - 可能是您的ActiveRecord版本中存在类似的隐藏错误save()

在Rails控制台中,猴子补丁update_attribute如下所示:

update_attribute()

然后尝试再次运行您的代码1 ...

你不应该看到“Changed?:false”..如果它返回false,虽然你改变了属性,但你的ActiveRecord版本中有一个错误,你应该报告它。

代码1:

注意:在这里检查update_attribute()(单数)的定义: (请阅读有关验证的细则 - 使用该方法听起来不是一个好主意)

http://ar.rubyonrails.org/classes/ActiveRecord/Base.html#M000400

另见:

Rails: update_attribute vs update_attributes

update_attribute()的源代码如下所示:

class ActiveRecord::Base
  def update_attribute(name, value) # make sure you use the exact code of your Rails Version here
    send(name.to_s + '=', value)
    puts "Changed?: #{changed?}"        # this produced false in the OP's scenario
    puts "valid?: #{valid?}"
    puts "errors: #{errors.inspect}"
    save
  end
end

如果属性的脏跟踪存在错误,它可能会失败...

代码2:

第二个代码看起来是正确的。

还有几件事要考虑:

1)您通过attr_accessible将哪些属性定义为可访问?

e.g。只有可访问的属性才会通过update_attributes()

更新

http://apidock.com/rails/ActiveRecord/Base/update_attributes

2)您使用哪些验证?

您确定在调用update_attribute?

时验证的验证是否通过

另见:

http://guides.rubyonrails.org/active_record_querying.html

http://m.onkey.org/active-record-query-interface

http://api.rubyonrails.org/classes/ActiveRecord/Base.html