如何在单表继承运行的子类的验证? [英] How to run validations of sub-class in Single Table Inheritance?

查看:149
本文介绍了如何在单表继承运行的子类的验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序,我有一类叫做预算。该预算可以是多种类型的..例如,假设有两个预算:FlatRateBudget和HourlyRateBudget。无论继承类预算。

In my application, I have a class called Budget. The budget can be of many types.. For instance, let's say that there are two budgets: FlatRateBudget and HourlyRateBudget. Both inherit from the class Budget.

这是我弄到:

class Budget < ActiveRecord::Base
  validates_presence_of :price
end

class FlatRateBudget < Budget
end

class HourlyRateBudget < Budget
  validates_presence_of :quantity
end

在控制台,如果我做的:

In the console, if I do:

b = HourlyRateBudget.new(:price => 10)
b.valid?
=> false
b.errors.full_messages
=> ["Quantity can't be blank"]

由于预计。

问题是,类型字段中,性传播感染,来自PARAMS ..所以我需要做的是这样的:

The problem is that the "type" field, on STI, comes from params.. So i need to do something like:

b = Budget.new(:type => "HourlyRateBudget", :price => 10)
b.valid?
=> true

这意味着轨道运行在超一流的验证,而不是实例的子类后,我设置了类型。

Which means that rails is running validations in the super-class instead of instantiating the sub class after I set up the type.

我知道这是预期的行为,因为我实例化忽略了最低的需求量场的一类,但我不知道是否有反正告诉轨运行验证的子类,而不是超。

I know that is the expected behaviour, since I'm instantiating a class that dosen't need the quantity field, but I wonder if there is anyway to tell rails to run the validations for the subclass instead of the super.

推荐答案

您也许可以解决这个问题有一个自定义的验证器,类似于这个问题的答案:的两种型号,一种性病和验证的但是,如果你可以简单地实例预期的子类型,首先,你会避免需要对于完全自定义验证在这种情况下。

You could probably solve this with a custom validator, similar to the answer on this question: Two models, one STI and a Validation However, if you can simply instantiate the intended sub-type to begin with, you would avoid the need for a custom validator altogether in this case.

正如您所注意到,单独设置类型字段不会奇迹般地从一种类型到另一种改变一个实例。尽管ActiveRecord的将使用键入字段从数据库实例化后的的对象适当的类,围绕做它的其他方式(实例超,然后手动)更改类型字段并没有改变,而你的应用程序正在运行的对象类型的效果 - 它只是不工作的方式

As you've noticed, setting the type field alone doesn't magically change an instance from one type to another. While ActiveRecord will use the type field to instantiate the proper class upon reading the object from the database, doing it the other way around (instantiating the superclass, then changing the type field manually) doesn't have the effect of changing the object's type while your app is running - it just doesn't work that way.

自定义的验证方法,在另一方面,能够独立检查键入字段,实例化适当类型的副本(基于对<$ C的值$ C>键入字段),然后在该对象上执行 .valid?,导致在子类中的验证运行于一个这似乎是一个动态的,即使它实际上是在制造过程中的适当的子类的实例的方式

The custom validation method, on the other hand, could check the type field independently, instantiate a copy of the appropriate type (based on the value of the type field), and then run .valid? on that object, resulting in the validations on the sub-class being run in a way that appears to be dynamic, even though it's actually creating an instance of the appropriate sub-class in the process.

这篇关于如何在单表继承运行的子类的验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆