2010-10-29 61 views
36

我已經瀏覽了Ruby on Rails指南,我似乎無法弄清楚如何防止某人刪除父記錄(如果它有孩子)。例如。如果我的數據庫有客戶,並且每個客戶可以有多個ORDERS,我想要防止有人刪除客戶,如果它在數據庫中有任何訂單。如果客戶沒有訂單,他們應該只能刪除一個客戶。如何防止刪除家長,如果它有子記錄?

定義模型之間的關聯以執行此行爲時有沒有辦法?

回答

43

你可以在回調中做到這一點:

class Customer < ActiveRecord::Base 
    has_many :orders 
    before_destroy :check_for_orders 

    private 

    def check_for_orders 
    if orders.count > 0 
     errors.add_to_base("cannot delete customer while orders exist") 
     return false 
    end 
    end 
end 

編輯

看到this answer一種更好的方式來做到這一點。

+5

這是最好的方式。這是最乾淨的,如果我正在處理你的代碼,它正是我要尋找這樣一個過濾器的地方。在回調中返回「false」是告訴導軌不要繼續操作。 – 2010-10-29 17:22:36

+0

'has_any ...?':) – 2010-10-29 17:29:39

+0

謝謝,喬。不,我沒有發明一種新的關聯類型... – zetetic 2010-10-29 17:33:15

0

嘗試使用filters在請求處理過程中掛接自定義代碼。

0

一種可能性是避免在這種情況下爲用戶提供刪除鏈接。

link_to_unless [email protected]? 

另一種方法是在你的控制器來處理這個問題:

if [email protected]? 
    flash[:notice] = "Cannot delete a customer with orders" 
    render :action => :some_action 
end 

或者,喬建議,before_filters可以很好地工作在這裏,並很可能是這樣做的更乾的方式,尤其是如果你想要這種類型的行爲而不僅僅是客戶。

81
class Customer < ActiveRecord::Base 
    has_many :orders, :dependent => :restrict # raises ActiveRecord::DeleteRestrictionError 

編輯:像Rails 4.1的,:restrict是不是一個有效的選項,而你應該使用:restrict_with_error:restrict_with_exception

例如:

class Customer < ActiveRecord::Base 
    has_many :orders, :dependent => :restrict_with_error 
+0

謝謝!乾淨;)我認爲,參考。完整性默認在Rails中... – luigi7up 2014-06-26 19:47:41

+1

限制信息是否可以自定義? – 2015-01-27 20:57:19

+2

請更新此答案以反映Rails 4.1及更高版本中的更改嗎? 「刪除了對不推薦使用的選項的支持:限制:依賴於關聯。」 http://edgeguides.rubyonrails.org/4_1_release_notes.html。 :依賴選項必須是[:destroy,:delete_all,:nullify,:restrict_with_error,:restrict_with_exception]之一 – Marklar 2015-03-17 03:24:15

相關問題