[英]Rails: querying associations during validation
在驗證期間,我想查詢關聯,但由於 ActiveRecord 的驗證風格,這兩種解決方案似乎都不是很好。 這是一個例子:
class User < ApplicationRecord
has_many :borrowed_books
validate :should_only_borrow_good_books
def should_only_borrow_good_books
# What I want but it does not work:
#
# unless borrowed_books.where(condition: "bad").empty?
# errors.add(:borrowed_books, "only good books can be borrowed")
# end
#
# ^ this query always returns an empty array
# This approach works but it's not ideal:
unless borrowed_books.all? { |b| b.condition == "good" }
errors.add(:borrowed_books, "only good books can be borrowed")
end
end
end
class BorrowedBook < ApplicationRecord
belongs_to :user
# attr: condition - ["bad", "good"]
end
另一種選擇是將驗證移至BorrowedBook
,使用類似validates :condition, inclusion: { in: %w(good) }, if: -> { user_id.present? }
並可能在User
中驗證關聯,例如validates_associated :borrowed_books
validates :condition, inclusion: { in: %w(good) }, if: -> { user_id.present? }
但我不喜歡這種方法,因為它通過將屬於User
的邏輯移動到BorrowedBook
使事情復雜化。 像這樣的一些驗證,你的應用程序可能會變得非常混亂。
這種驗證絕對應該保留在用戶模型中。 我不同意如果有多個條件它會看起來很亂。 如果它變得混亂,通常表明您應該拆分模型或在那里重構代碼。 模型工作使您能夠訪問和驗證來自 db 的數據。 改進當前代碼的一種方法是將條件列轉換為枚舉,參考:https ://api.rubyonrails.org/v5.1/classes/ActiveRecord/Enum.html 可以這樣寫
class User < ApplicationRecord
has_many :borrowed_books
validate :should_only_borrow_good_books
private
def should_only_borrow_good_books
return unless books.not_good.any?
errors.add(:borrowed_books, "only good books can be borrowed")
end
end
end
class BorrowedBook < ApplicationRecord
belongs_to :user
enum status: [ :good, :bad ]
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.