[英]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_reference
的foreign_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.