2011-11-15 149 views
2

我想将answers表中的内容与ActiveRecord交换。
代码1:无法使用ActiveRecord更新属性

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={}> 
+0

其ActiveRecord的版本,您使用的?例如哪个Rails版本? – Tilo

+0

@Tilo Rails和ActiveRecord的版本都是'3.1.1'。 –

+0

@Tilo看起来对象没有改变,我只改变了'str'的​​值。 –

回答

0

可能的ActiveRecord 3.1.1错误

向我提到,他在独立脚本使用require "active_record"(不使用轨道亚军)的OP。 他的任务没有单独的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()触发属性的脏跟踪,然后错误地假定对象未改变的错误,并因此它不会被坚持,尽管update_attribute()的执行调用save()(见下面的代码片段)。

我见过这样的事情与Mongoid的旧版本 - 可能是因为有一个在您的ActiveRecord版本类似的隐藏错误的update_attribute()

在Rails的控制台猴子补丁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 

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

你不应该看到“已更改?:假” ..如果返回false,尽管你改变了属性,那么你的ActiveRecord版本中有一个错误,你应该报告它。

代码1:

注意:检查update_attribute()(单数)在这里的定义是: (请阅读关于验证的精细打印 - 它听起来并不像一个好主意,用该方法)

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

参见:

Rails: update_attribute vs update_attributes

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

2260:  def update_attribute(name, value) 
2261:   send(name.to_s + '=', value) 
2262:   save 
2263:  end 

是否存在与属性的脏跟踪的错误也可能会失败......

代码2:

第二个代码看起来正确。

有几件事情也考虑:

哪些属性你定义为访问,通过attr_accessible 1)?

例如只有访问属性将通过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

+0

我用'attr_accessible'定义':content'。::除了'Text'类型之外,内容没有其他验证。 –

+0

被update_attribute()以某种方式覆盖? – Tilo

+0

http://stackoverflow.com/questions/6722335/weird-relationship-behavior-on-rails-3-and-update-attribute – Tilo