簡體   English   中英

在Rails中進行設置時,驗證關聯的模型是否存在

[英]Validate that the associated model exists when set in Rails

假設我們在Rails中具有以下Post模型:

class Post < ActiveRecord::Base
  belongs_to :user
end

user不是必需的,但是在設置用戶名后,我們希望它成為有效的關聯(我們不希望發布的帖子中的user_id不在數據庫中)。 測試失敗:

expect(Post.new).to be_valid
expect(Post.new(user_id: 0)).not_to be_valid
expect(Post.new(user: User.create)).to be_valid

一種解決方案是:

validates_presence_of :user, unless: "user_id.nil?"

這將完成所需的任務,但並不是很漂亮,因為我們不想為應用程序中的每個belongs_to編寫它。

有沒有辦法告訴Rails檢查關聯模型的存在? 這不是我們默認想要的東西嗎? (為什么我們要一個不指向任何東西的association_id ?)

為了確保關聯在數據庫級別有效,MySQL和PostgreSQL能夠強制表上外鍵列的有效性。 從Rails 4.2開始 ,可以在遷移過程中創建這些外鍵約束。

您可以在遷移中至少以兩種方式執行此操作。 要么將foreign_key屬性傳遞給add_reference

add_reference :posts, :user, index: true, foreign_key: true

或在add_reference加上add_foreign_key ,這也使您可以選擇在刪除用戶時重置密鑰:

add_reference :posts, :user, index: true
add_foreign_key :posts, :user, on_delete: :nullify

通過將哈希傳遞給add_referenceforeign_key屬性來組合兩種方法(從Rails 4.2.1開始):

add_reference :posts, :user, index: true, foreign_key: {on_delete: :nullify}

如果查詢通過更新user_id以指向不存在的用戶來打破外鍵約束,則查詢將失敗並在Rails中引發異常。

如前所述,您還可以創建一個驗證以在創建Post之前檢查User存在。 但是,這不能像數據庫上的外鍵約束那樣有力的保證,因為可以在通過驗證和創建Post之間的時間內刪除User

為了幫助保持引用在應用程序級別上的有效性,通常最好的做法是避免將用戶ID直接傳遞給Post構造函數。 而是嘗試始終使用User對象作為輸入,例如通過調用User.find(:id)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM