繁体   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