2014-05-23 40 views
15

我有複雜的模型/表單。我不想重複記錄,所以我想合併具有相似屬性的記錄。我將如何使用before_save回調取消「保存」?這是我在想什麼:Rails 4:如何取消「before_save」回調中的保存?

class ProductsColor < ActiveRecord::Base 


    before_save :check_for_similar_record 

    def check_for_similar_record 
    if ProductsColor.exist?(color_id: self.color_id, product_id: self.product_id) 
     # merge values with existing ProductsColor and stop self from saving 
    end 
    end 

end 

回答

22

爲了防止記錄被保存,你應該簡單地返回false

def check_for_similar_record 
    if ProductsColor.exists?(color_id: self.color_id, product_id: self.product_id) 
    # merge values 
    false 
    else 
    true 
    end 
end 
+11

如果您返回nil,該記錄仍將保存,您必須顯式返回false才能取消保存。 – dezman

+1

對於Rails 5來說,這已經不再是真實的 - 請參閱其他答案以獲取詳細信息。 –

+0

@JonGjengset的問題是「Rails 4:如何取消」before_save「回調中的保存?」。我爲此得到了這個投票嗎? –

40

Rails的5

As of Rails 5,你可以表明的操作應通過在您的回調中明確呼叫throw :abort來中止。在cancelling callbacks(現在)的文檔部分規定:

如果before_*回調throws :abort,所有後來的回調和相關動作被取消。

transactions下節繼續說:

如果before_*回調取消發出一個ROLLBACK的動作。您還可以觸發ROLLBACK在任何回調中引發異常,包括after_*掛鉤。

軌道4

這個故事是非常類似於Rails的5,但回調應該改爲返回false。的the documentation相應部位有益指出

如果before_*回調返回false,所有後來的回調和相關動作被取消。如果after_ *回調返回false,則後面的所有回調都將被取消。

其次

如果before_ *回調取消發出一個ROLLBACK的動作。您還可以觸發ROLLBACK在任何回調中引發異常,包括after_ *鉤子。

+0

另請參閱:** Rails 5丟棄中止:我如何設置錯誤消息?** http://stackoverflow.com/questions/38625276/rails-5-throw-abort-how-do-i-setup-錯誤消息 – prograils

+0

如果您希望它默默無聞地保存,該怎麼辦?例如防止關聯表中的重複關聯。在這種情況下無需拋出錯誤... Rails 5 – Micah

相關問題