2012-08-28 66 views
0

我遇到了Rails'save方法的問題;它應該是失敗的,但在它應該的時候沒有成功。保存方法回滾並在有效時返回nil

我有一個Claim模型,可以與任何Status保存,但如果它被提交(status_id == 5),那麼條款和條件必須被接受。

validates :terms_and_conditions, :acceptance => {:accept => true, :if => :submitted?} 

def submitted? # simplified for this example 
    status_id == 5 
end 

然而,我還存儲所述時間,術語已被接受(分貝字段tnc_accepted_at下),並且限定terms_and_conditions作爲這一領域的存在。 (這一點工作正常,我只是不知道它是否與我的問題有關。)

def terms_and_conditions 
    tnc_accepted_at.present? 
end 

def terms_and_conditions=(bool) # browser will pass '0' or '1' 
    self.tnc_accepted_at = bool.in?([false, nil, 0, '', '0']) ? nil : DateTime.now 
end 

但是,這裏是擦。

claim 
=> #<Claim id: 51, tnc_accepted_at: nil, status_id: 4> 
claim.valid? 
=> true 

然後我嘗試提交:索賠在這種狀態下開始了

claim.update_attributes! :status_id => 5 
    (0.3ms) BEGIN 
    ClaimItem Load (1.5ms) SELECT --blah blah blah 
    Status Load (0.6ms) SELECT --blah blah blah 
    (0.4ms) ROLLBACK 
ActiveRecord::RecordInvalid: Validation failed: Terms and conditions must be accepted 

...這是完美的,但是當我試圖糾正錯誤:

claim.update_attributes! :terms_and_conditions => true 
    (0.3ms) BEGIN 
    ClaimItem Load (1.1ms) SELECT --blah blah blah 
    (0.7ms) UPDATE "claims" --blah blah blah 
    (0.2ms) ROLLBACK 
=> nil 

......這很奇怪!而且我注意到,我也得到這個任何時候,我嘗試保存記錄,不管組情況(使用savesave!update_attributesupdate_attributes!:tnc_accepted_at => DateTime.now,沒關係)下 - 如果它是有效,它回滾並返回零;如果它是無效,錯誤如您所料。

+0

版本:rails 3.1.0; pg 0.11; 「PostgreSQL 9.1。5在x86_64-unknown-linux-gnu上,由gcc(Ubuntu/Linaro 4.6.3-1ubuntu5)4.6.3,64位「(Ubuntu 12.04'Precise Pangolin')編譯。想不到任何其他的東西 – PJSCopeland

+0

NB。我沒有在'tnc_accepted_at'上直接放置'presence'驗證器的原因是因爲該字段不在視圖中,而是我有一個'terms_and_conditions'複選框,並且我想讓錯誤 – PJSCopeland

+0

另外,當在新的'claim'上嘗試這個時,'id','created_at'和'updated_at'字段_do_被填充,Rails認爲它不再是新記錄。希望這會有幫助確定問題發生的位置... – PJSCopeland

回答

0

當然這是很簡單的東西,以後我就可以花一整天......

如此看來update_attributes只是正常工作在具有已保存記錄。

> claim 
=> #<Claim id: 51, tnc_accepted_at: nil, status_id: 4> 
> claim.valid? 
=> true 
#========= 
> claim.save # This makes all the difference! 
    (0.3ms) BEGIN 
    Claim Load (0.4ms) SELECT --blah blah blah 
    (1.0ms) INSERT INTO "claims" --blah blah blah 
    (14.8ms) COMMIT 
=> true 
#========= 
> claim.update_attributes! :status_id => 5 
    (0.3ms) BEGIN 
    ClaimItem Load (1.5ms) SELECT --blah blah blah 
    Status Load (0.6ms) SELECT --blah blah blah 
    (0.4ms) ROLLBACK 
ActiveRecord::RecordInvalid: Validation failed: Terms and conditions must be accepted 
# ... just as expected. 
> claim.update_attributes! :terms_and_conditions => true 
    (0.3ms) BEGIN 
    ClaimItem Load (0.8ms) SELECT --blah blah blah 
    (0.8ms) UPDATE "claims" --blah blah blah 
    (11.4ms) COMMIT 
=> true 
# ... hooray! 
+0

儘管奇怪地說,'claim.terms_and_conditions = true; claim.status_id = 5; claim.save'(以有效的'claim'開始)仍然回退並返回nil。至少我儘管如此,我找到了一些方法來使它工作。 – PJSCopeland

2

也許這個問題是老的?

我認爲問題是"new record"標誌(如你所建議的)。如果保存了新記錄,"new record"設置爲false,但是如果回滾,則"new record"仍然具有值false,就像保存中其他填充的列將保持其值一樣。 如果嘗試了新的保存(使用正確的值),Rails中的save方法將執行db-update而不是db-insert,因爲"new record"爲false。

我注意到這是一個非常老的Rails版本,認爲現在它會被修復。我固定它用的ActiveRecord :: Base的這個方法(Rails的還是必須使用@new_record內部這個工作)

def try_reset_new_record! 
    if ! self.new_record? && 
     (! self.id || ! self.class.find_by_id(self.id)) 
    @new_record = true 
    end 
end 
0

另一個原因是一個ActiveRecord save方法將返回零,如果是被嘲笑它。類似於expect(modelInstance).to receive(:save)