2012-04-06 52 views
6

有沒有辦法在before_destroy鉤子內檢查什麼對象(類)叫做destroyhas_many通過關聯依賴destroy在誰被調用destroy的情況下

在下面的例子中,當一個patient被銷燬時,他們的appointments(這是我想要的)也是如此。但是我不想讓physician被銷燬,如果有任何appointmentsphysician相關聯。

同樣,有沒有辦法在before_destory回調中做這樣的檢查?如果沒有,是否有其他方式根據呼叫的「方向」(即基於誰的呼叫)完成這個「銷燬檢查」?

class Physician < ActiveRecord::Base 
    has_many :appointments, dependent: :destroy 
    has_many :patients, through: :appointments 
end 


class Patient < ActiveRecord::Base 
    has_many :appointments, dependent: :destroy 
    has_many :physicians, through: :appointments 
end 


class Appointment < ActiveRecord::Base 
    belongs_to :patient 
    belongs_to :physician 

    before_destroy :ensure_not_referenced_by_anything_important 

    private 

    def ensure_not_referenced_by_anything_important 
    unless patients.empty? 
     errors.add(:base, 'This physician cannot be deleted because appointments exist.') 
     false 
    end 
    end 
end 

回答

11

只是說:

class Physician < ActiveRecord::Base 
    has_many :appointments, dependent: :restrict_with_exception 
    has_many :patients, through: :appointments 
end 

注意dependent: :restrict_with_exception。這將導致Active Record拒絕銷燬與Appointment記錄關聯的任何Physician記錄。

請參閱the API docsthe association basics guide

+0

[':restrict'被廢棄(https://github.com/rails/rails/commit/5ad79989ef0a015fd22cfed90b2e8a56881e6c36#diff-5870816b49b90e43340607bb11ed2514R91)2012年8月10日在去往'的Rails 4'一個分支。 [*關聯基礎知識*指南也進行了更新](https://github.com/rails/rails/commit/a63fc94aa3689f1e781ac51411ec79a81c011d8a)。 ':restrict_with_exception'提供與':restrict'相同的功能;還有另外一個類似的選項':restrict_with_error',如果有關聯的對象會導致錯誤被添加到所有者。 – user664833 2014-03-21 23:47:07

15

注意dependent: :destroyhas_many :through關係只刪除協會和相關記錄(即的連接記錄將被刪除,但相關記錄將不)。所以如果你刪除一個patient它只會刪除appointment而不是physician。請閱讀the API docs中的詳細說明。

我已經粘貼了下面的相關段落。

什麼被刪除?

這裏有一個潛在的缺陷:has_and_belongs_to_manyhas_many :through關聯在連接表中有記錄,以及關聯的記錄。所以當我們調用其中一種刪除方法時,究竟應該刪除哪些內容?

答案是,假定關聯上的刪除是關於刪除所有者和關聯對象之間的鏈接,而不是關聯對象本身。因此,與has_and_belongs_to_manyhas_many :through,連接記錄將被刪除,但關聯的記錄不會。

這是有道理的,如果你想想看:如果你打電話給post.tags.delete(Tag.find_by_name('food'))你想的food標籤從post是無關聯,而不是標籤本身從數據庫中刪除。

+0

很好的解釋,謝謝!我很難確定是否依賴於::銷燬刪除了協會和另一方的記錄。 – Arel 2013-05-23 20:40:13

+0

這似乎是一個徹底的答案,但是,我已經按照你的說法設置了它,當我嘗試刪除一個Patient(使用rails管理員)時,醫師也被刪除。 – 2015-05-19 15:33:45

相關問題