验证多态关联的引用完整性
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 的实际阶梯记录 table。
在 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 的实际阶梯记录 table。