gpt4 book ai didi

ruby-on-rails - 如何在单表继承中运行子类的验证?

转载 作者:行者123 更新时间:2023-12-03 23:28:46 25 4
gpt4 key购买 nike

在我的应用程序中,我有一个名为 Budget 的类。预算可以有多种类型。例如,假设有两种预算:FlatRateBudget 和 HourlyRateBudget。两者都继承自Budget 类。

这是我到目前为止所得到的:

class Budget < ActiveRecord::Base
validates_presence_of :price
end

class FlatRateBudget < Budget
end

class HourlyRateBudget < Budget
validates_presence_of :quantity
end

在控制台中,如果我这样做:
b = HourlyRateBudget.new(:price => 10)
b.valid?
=> false
b.errors.full_messages
=> ["Quantity can't be blank"]

正如,预期。

问题是 STI 上的“类型”字段来自 params.. 所以我需要做一些类似的事情:
b = Budget.new(:type => "HourlyRateBudget", :price => 10)
b.valid?
=> true

这意味着 rails 在父类(super class)中运行验证,而不是在我设置类型后实例化子类。

我知道这是预期的行为,因为我正在实例化一个不需要数量字段的类,但我想知道是否有任何方式告诉 rails 运行子类而不是 super 类的验证。

最佳答案

您可能可以使用自定义验证器解决此问题,类似于此问题的答案:Two models, one STI and a Validation但是,如果您可以简单地实例化预期的子类型,那么在这种情况下您将完全不需要自定义验证器。

正如您所注意到的,单独设置 type 字段并不会神奇地将实例从一种类型更改为另一种类型。而 ActiveRecord 将使用 type 上实例化正确类的字段阅读数据库中的对象,反过来(实例化父类(super class),然后手动更改类型字段)不会在您的应用程序运行时更改对象的类型 - 它只是不能那样工作。

另一方面,自定义验证方法可以检查 type字段独立,实例化适当类型的副本(基于 type 字段的值),然后运行 ​​.valid?在该对象上,导致对子类的验证以一种看似动态的方式运行,即使它实际上是在该过程中创建适当子类的实例。

关于ruby-on-rails - 如何在单表继承中运行子类的验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9229554/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com