2012-01-11 71 views
8

我有貨件和發票。Rails 3. before_destroy驗證以防止刪除父記錄

發票屬於裝運
裝運有一個發票

如果貨物確實有發票,則該貨物應不能夠被刪除。我需要在模型中進行設置,因爲我使用的是ActiveAdmin。

所以,我做這shipment.rb

has_one :invoice 
before_destroy :check_for_invoice 

private 

def check_for_invoice 
    unless invoice.nil? 
    self.errors[:base] << "Cannot delete shipment while its invoice exists." 
    end 
end 

但我只是得到一個黃色的消息說「貨不能刪除」,但它實際上刪除。

如何防止裝運被刪除?

回答

23

before_destroy回調需要一個真/假值,以確定是否要proceeed。

添加return falsecheck_for_invoice像這樣:

has_one :invoice 
before_destroy :check_for_invoice 

private 

def check_for_invoice 
    unless invoice.nil?  
    self.errors[:base] << "Cannot delete shipment while its invoice exists." 
    return false 
    end 
end 
+0

啊,沒錯!我忘了回覆錯誤。我還發布了這部分代碼錯誤,如果invoice.nil ?,它應該是',除非invoice.nil?'。 – leonel 2012-01-11 19:51:53

+0

我對這種邏輯很好奇 - 但認爲它可能只是你在做的事情。我會更新我的答案,以便與後代的緣故相匹配。 – 2012-01-11 20:07:47

+0

檢查[對類似問題的此答案](http://stackoverflow.com/a/10257516/703233)爲更好的方法來執行此操作。 – nitsas 2016-04-06 09:49:34

3

docs

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

那麼試試這個:

self.errors[:base] << "Cannot delete shipment while its invoice exists." and return false 
+0

@Jordan你說得對,'return'大多不地道在Ruby中,但如果該行是不是在方法的最後一個(再加上考慮重構)?或者,如果您稍後在方法中添加其他語句並忘記添加回車?我認爲這些就是你爲什麼要在rails項目中看到'並返回false'的原因...... – maprihoda 2012-01-11 20:11:05

+0

好的,這是一個足夠引人注目的論據。我回滾了我的修訂。 – 2012-01-11 21:11:17

4

我的2美分shipment.rb

has_one :invoice, dependent: :restrict 

我認爲它會工作,我看到了另一個線程此解決方案。我現在在我的模特里嘗試。

1

對於軌道4,5:

class Shipment < ActiveRecord::Base 
    has_one :invoice, dependent: :restrict_with_error 

會做的伎倆。如果您想要例外而不是錯誤,請使用:restrict_with_exception。請參閱the relevant api docs page

對於Rails 3中(也許更早太)嘗試:

class Shipment < ActiveRecord::Base 
    has_one :invoice, dependent: :restrict