簡體   English   中英

驗證多態關聯的參照完整性

[英]Validating referential integrity of a polymorphic association

在Rails應用程序中工作,我將一個可選的belongs_to關聯更改為多態。 現有的代碼正在驗證關聯的引用完整性,我正在嘗試弄清楚如何將其轉換為多態習慣用法。

一個簡化但說明性的示例...

老人:

class Climb < ActiveRecord::Base

  belongs_to :ladder
  validate   :ladder_exists_if_id_set

  def ladder_exists_if_id_set
    if ladder_id.present? && Ladder.find_by_id(ladder_id).blank?
      errors.add('Ladder id', 'invalid. Set a different ladder id or nil.')
    end
  end

end

新的:

class Climb < ActiveRecord::Base

  belongs_to :climbable, polymorphic: true
  validate   :climbable_exists_if_set

  def climbable_exists_if_set
    return unless climbable_id.present? && climbable_type.present?

    klass = climbable_type.constantize

    if klass.find_by_id(climbable_id).blank?
      errors.add("#{klass} id", "invalid. Set a different #{klass} id or nil.")
    end
  end

end

這似乎可行,但這是正確的方法嗎? 似乎我正在重新實現多態為您提供的動態getter / setter方法。

旁注 :我可以忽略僅設置_type_id的情況,因為Rails在這種情況下會使記錄無效。

我想知道,為什么首先要以這種方式在舊代碼中驗證id的唯一性? 編寫validates :ladder_id, uniqueness: true, allow_nil: true [, allow_blank: true] (you should decide what you want to allow) ,並在需要時使用自定義消息是不是更容易。 然后在新代碼中查看Rails是否為您處理了多態關聯。 我認為您不需要您的climbable_exists_if_set。

發表評論后

這可能更容易。 您只需要驗證梯形圖對象的存在。 注意,不是一個ladder_id,而是一個對象本身,因此您的驗證應如下所示:

validates :ladder, presence: true, allow_nil: true [, allow_blank: true]

在這種情況下,Rails會驗證您的梯形表中是否存在具有給定ID的實際梯形記錄。

暫無
暫無

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

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