2011-11-15 112 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